Skip to main content

Troubleshooting

Find the cause of common rendering, styling, submission, and JSX errors.

Troubleshoot by error

Start with the message or failed operation you can see. Each guide follows that failure from meaning to repair and verification.

The form renders unstyled under Tailwind v3

Symptom
The form works but looks bare — no borders, spacing, or button styling.
Cause
@usefillo/react/styles.css ships its rules in @layer components. Any unlayered CSS — Tailwind v3’s preflight, most resets — outranks every layered rule, so the default theme silently evaporates.
Fix
Import @usefillo/react/styles.unlayered.css instead. Details in the stylesheet matrix.

The hosted /f page doesn't match my embed

Symptom
appearance.classNames styling shows in your app but not on the hosted page or dashboard preview.
Cause
By design — classNames never sync; the hosted page renders the default renderer plus theme tokens only.
Fix
Put brand parity in theme tokens (defineForm({ theme }) or the dashboard theme); keep classNames for embed-only polish.

The form says “This form isn’t live yet” or eats submissions

Symptom
A code-defined form renders, but shows “This form isn’t live yet” in production (or a draft banner in dev) and refuses responses.
Cause
In a claimed workspace, code-defined forms sync as drafts and reject public submissions until a human publishes. A capped, unclaimed preview workspace can publish its first sync immediately.
Fix
If the resolved form is a draft, publish it in the dashboard. The browser console notice links straight to it, and staged schema changes need the same publish step.

A code change doesn't appear in the live form

Symptom
Development diagnostics report trusted_sync_required, while respondents continue seeing the previous published fields.
Cause
The project requires an authenticated schema credential, or the newer schema is staged but not published. Current renderers deliberately use the resolved live schema so a deploy cannot break the respondent flow.
Fix
Upgrade @usefillo/react or @usefillo/dom to the latest version. Stage the exact schema with authenticated fillo push --stage or a server-held FILLO_SYNC_TOKEN, then publish it from the dashboard. Do not enable publishable-key writes only to silence the diagnostic.

Submit fails with “Couldn’t reach the server”

Symptom
The form fails to load or submit with a network error while the rest of the site is fine.
Cause
An ad-blocker, corporate firewall, or your site's Content-Security-Policy is blocking requests to fillo.so.
Fix
Check the browser network tab for the blocked request. If your site sets a CSP, allow connect-src https://fillo.so. For ad-blockers and VPNs, retry with them off to confirm.

Blank form, or “useFillo must be used inside…”

Symptom
React only. The form renders nothing, or a component that is clearly inside the provider throws useFillo must be used inside <FilloForm> or <FilloProvider>.
Cause
Two copies of @usefillo/react (or of React itself) in the bundle — context identity differs across copies.
Fix
Dedupe to a single copy: npm dedupe / one version in the lockfile; in monorepos check hoisting and bundler aliases.

Submit warns “has a client but no submission target”

Symptom
The form renders and validates, but submitting does nothing — the console warns “This form has a client but no submission target — a bare schema can’t sync.”
Cause
A bare schema object was passed with a client but no identity: no defineForm() handle and no formId, so there’s nothing to submit to.
Fix
Wrap the schema in defineForm({ id, … }), author it as <Fillo.Form id="…"> (see the code-defined forms guide), or pass formId for a dashboard-built form.

JSX authoring errors

React only — these come from Fillo.* JSX authoring (@usefillo/react). Vue, Svelte, and @usefillo/dom define forms with defineForm() params instead, so none of this catalog applies. Mistakes in <Fillo.Form> authoring throw FilloJsxError with a stable code; the error message links straight to its entry below. To avoid them in the first place, read the code-defined forms guide.

jsx-missing_id

A block, an <Fillo.Option>, or <Fillo.Form> itself has no stable string id (1–128 chars); options also need a label.

Fix: Write a permanent id by hand — ids key responses, logic, piping, and sync, so never derive them from position or a counter.

jsx-duplicate_id

Two blocks share one id. Ids key responses and must be unique across the whole form, pages included.

Fix: Rename one. If the form is live, keep the id existing responses were stored under and rename the newcomer.

jsx-non_fillo_child

Something that isn't a Fillo element sits where the schema expects one — raw text or HTML inside <Fillo.Form>, children on a props-only field, or <Fillo.Option> outside a choice field.

Fix: Children define the schema: put text in <Fillo.Paragraph>, layout outside the form (or go headless with FilloProvider), and options inside Select, MultiSelect, Dropdown, or Ranking.

jsx-wrapper_component

A plain React component was used as a form child. The compiler never renders children, so wrappers are invisible to it.

Fix: Reuse via a plain function that returns Fillo elements and call it inline: {contactFields()}.

jsx-opaque_type

A child's component type is opaque — lazy/memo, or the JSX crossed a server-component boundary and arrived as a reference.

Fix: Define the form in a client module ("use client") and pass the compiled value across server/client boundaries, never the JSX.

jsx-unknown_prop

A prop isn't in that component's schema whitelist. Typos and className/style land here instead of vanishing silently.

Fix: Use the props in the component reference; styling lives on <Fillo.Form appearance={…}>, never in the schema.

jsx-option_prop_conflict

A choice field has both an options prop and <Fillo.Option> children, or a heading/paragraph has both a text prop and children.

Fix: Pick one source — both compile identically.

jsx-page_mix

<Fillo.Form> mixes <Fillo.Page> elements with loose blocks, or a Page/Option appears inside a page.

Fix: Children are either all pages or all blocks — wrap the loose blocks in a <Fillo.Page>.

jsx-text_child_required

A Heading or Paragraph has non-string children (expressions, elements), or no text at all.

Fix: Pass plain text as children or the text prop — piping tokens like {{name}} are fine.

jsx-rendered_inert

React actually rendered a Fillo.* field — it was used outside <Fillo.Form> / Fillo.defineForm(), often from a server component.

Fix: Keep fields inside <Fillo.Form>, and define the form in a client module ("use client").

This page for agents: /docs/troubleshooting.md · index at /llms.txt

Updated

Was this page helpful?