Skip to content

FAQ & Troubleshooting

The embed shows “This questionnaire is not available.”

Section titled “The embed shows “This questionnaire is not available.””

The public id resolves to nothing live. In order of likelihood:

  1. The questionnaire was never published. A draft isn’t visible to embeds — click Publish changes in the editor. (The live endpoint 404s until version 1 exists.)
  2. The public-id has a typo — copy it from the editor’s Embed panel.
  3. The api-base points at the wrong backend.

The embed shows “The questionnaire could not be loaded.”

Section titled “The embed shows “The questionnaire could not be loaded.””

The request itself failed. Check, in order:

  • Is the backend reachable from the browser? Open {api-base}/public/v1/questionnaires/{publicId}/live in a tab.
  • Mixed content: an https:// page cannot call an http:// api-base — browsers block it. Serve the backend over HTTPS.
  • Allowed origins: if the questionnaire has an origin list and your page’s origin isn’t on it, the browser blocks the read (the devtools console shows a CORS error). Add your origin in the Embed panel — exact match, scheme and port included.

The form renders, but a red “answers aren’t saving” banner appears

Section titled “The form renders, but a red “answers aren’t saving” banner appears”

Saves are failing after retries. The usual causes: the origin isn’t allowed (mutating calls return 403 — check the network tab), the backend went down mid-session, or a proxy strips the request. The form keeps the respondent’s answers in memory and keeps retrying on each screen change.

“This form is misconfigured: an external reference is required.”

Section titled ““This form is misconfigured: an external reference is required.””

The questionnaire’s submission policy is one-per-reference and the embed has no external-ref attribute. That’s a deliberate loud failure — add the reference. See External references.

A refreshed page doesn’t resume the session in a new tab / after a browser restart

Section titled “A refreshed page doesn’t resume the session in a new tab / after a browser restart”

By design. Resume uses sessionStorage, which is per-tab and doesn’t survive browser restarts — because with spoofable references, anything longer-lived would let a guessed reference unlock someone else’s session. Cross-device resume arrives with signed references (roadmap).

The React/Angular wrapper doesn’t accept labels / completion-redirect / persist-session

Section titled “The React/Angular wrapper doesn’t accept labels / completion-redirect / persist-session”

Correct — the current wrappers expose publicId, apiBase, and externalRef only. Use the web component directly for the rest; it’s the same renderer. See the note in React / Angular.

My “not equals” rule doesn’t fire for people who haven’t answered yet

Section titled “My “not equals” rule doesn’t fire for people who haven’t answered yet”

By design: no condition is ever true against an unanswered question, including not equals. “Show unless they picked X” therefore means “show once they picked something other than X”. The same applies to does not contain and to equals false on an untouched toggle. Full semantics: Rules.

An answer disappeared when I changed an earlier answer

Section titled “An answer disappeared when I changed an earlier answer”

That’s answer clearing: hiding a question deletes its answer, and the clearing cascades through dependent rules. It’s what keeps hidden answers from secretly driving logic. Details.

Why can’t a rule reference my file-upload question?

Section titled “Why can’t a rule reference my file-upload question?”

There’s nothing meaningful to compare — rules would end up matching on file names. File questions can have rules; they can’t be referenced by them. Why.

Uploads fail with cryptic DNS or 403 errors

Section titled “Uploads fail with cryptic DNS or 403 errors”

Check S3_PATH_STYLE first. MinIO, R2, B2, and most S3-compatibles need true (path-style); real AWS needs false. This is the single most common storage misconfiguration. Storage.

The backend won’t start and mentions a “canary”

Section titled “The backend won’t start and mentions a “canary””

Working as intended: the startup canary write/read/delete failed, so the backend refused to start rather than accept uploads it would lose. The error message names the settings to check (bucket exists? credentials? path writable?).

The server verifies file content, not names. A .pdf that is really a zip, a .csv that contains binary, or anything that sniffs as HTML/script is rejected with a specific message. If the file is genuinely what its extension claims and still bounces, that’s a bug worth reporting.

Autocomplete degrades silently when the geocoder is unreachable — manual entry keeps working, so nothing looks “broken”. Check that PHOTON_BASE_URL is reachable from the backend, remember suggestions start at the third typed character, and note the public Photon instance is fair-use (it may throttle you — self-host for production).

All your test traffic comes from one IP, and the public API rate-limits per IP. Set FORMS_RATE_LIMIT_ENABLED=false in development. If this happens in production behind a reverse proxy, you’ve likely hit the proxy-IP problem — every visitor is sharing one bucket. Fix: rate limiting behind a proxy.

The editor’s questionnaire list stops at 100

Section titled “The editor’s questionnaire list stops at 100”

Known limitation: the list shows the 100 most recently updated questionnaires and has no pager yet. The management API paginates (GET /api/v1/questionnaires?page=&size=) if you need the rest.

CSV values show a leading apostrophe in Excel

Section titled “CSV values show a leading apostrophe in Excel”

That’s the formula-injection guard: text answers starting with =, +, -, or @ are quote-prefixed so respondent input can’t execute as a formula. The apostrophe is Excel’s “treat as text” marker and doesn’t appear in the stored data.

Responses: the responses collection in MongoDB (docker compose exec mongo mongosh forms_engine --eval 'db.responses.find().pretty()'). Definitions and versions: questionnaires and questionnaire_versions. Uploaded file index: uploaded_files; the bytes are in your storage backend under server-generated keys.

Why doesn’t a response appear the moment someone opens the form?

Section titled “Why doesn’t a response appear the moment someone opens the form?”

Response creation is lazy — it happens on the first forward navigation or first upload, so page views don’t create empty rows. Lifecycle.