Appearance
Troubleshooting & FAQ
The problems people hit most often, and how to fix them. Each answer points at the underlying behaviour so you can tell what went wrong.
My flow returns a 500
A 500 from a flow means a node failed and the error was not caught. Two things to check:
- Read the run. Open the project's run history and find the failed run. It shows which node failed and the error message, so you know exactly where to look.
- See the trace. Add
?_trace=1to the request URL. FlowRunner then includes a step-by-step trace of every node in the response body, with timings and the point of failure.
To make the failure graceful instead of a 500, wire the failing node's error port to a branch that handles it — a failing node routes to its error port when one is connected, and only surfaces as a 500 when it is not. See Error handling.
TIP
A 500 is the flow itself failing. A 400 is different — it means the request did not match the flow's declared inputs (a missing required field or the wrong type). Fix a 400 by sending the input the Start node expects. A 429 means you have hit the rate limit; wait and retry.
Where is my endpoint URL?
Every flow that begins with a Start node is exposed as an HTTP endpoint at:
/api/run/<projectId>/<flow-name>The <flow-name> is a slug of the flow file's name (lowercased, spaces to hyphens). The HTTP method must match the method configured on the Start node — a Start set to POST only answers POST. A mismatched method, an unknown path, or a flow with no Start node all return 404. See Testing & the trigger URL and HTTP triggers.
My form is not submitting
Work down this list:
- Is it a form file? Only files of type form accept submissions. A page built without form inputs has nothing to submit.
- Are required fields filled? FlowRunner validates required fields on the server. A submission missing one comes back with
400and the list of missing field names — client-side validation can be bypassed, so the server always re-checks. - Are you within the limits? Submissions are rate-limited (30 per minute per IP) and capped at 100 KB. Bursts return
429; oversized payloads return413. - Did a bot fill the honeypot? Forms include a hidden anti-spam field. If it is filled, FlowRunner responds as if the submission succeeded but silently drops it — legitimate users never see or touch that field.
- Did you publish? The public sees the last published version. If you changed the form but did not publish, visitors are using the older snapshot.
Your submissions are stored by default, so check the responses inbox to confirm what actually arrived. See Form submissions.
My email is not sending
FlowRunner sends email (the Email node and workspace invites) through Resend, which needs an API key. Without RESEND_API_KEY, email degrades gracefully — the flow still runs, the submission is still captured, and the invite link is still created — but no message is actually delivered. The email step simply reports that no provider is configured.
To turn on real delivery, set these environment variables and restart:
bash
RESEND_API_KEY=<your Resend API key>
EMAIL_FROM="Your Business <noreply@yourdomain.com>"EMAIL_FROM is optional but recommended — without it, messages send from a default sender. Email sending never throws, so a delivery failure will not crash a flow; check your logs for the reason (for example, no_provider or a provider error code). See Environment variables.
My secrets are not resolving
${secrets.NAME} reads from your workspace's encrypted vault at run time. If a reference is coming back empty, check each of these:
- Is the vault enabled? The secrets vault requires
SECRETS_KEY(a 32-byte base64 value). Without it, no secrets are stored or resolved, and setting one returns an error. See Secrets. - Does the secret exist in this workspace? Secrets are per-workspace. A secret set in your personal workspace is not visible to a flow in a team workspace, and vice versa.
- Is the name valid and exact? Secret names must start with a letter or underscore and contain only letters, numbers, and underscores.
${secrets.API_KEY}and${secrets.apikey}are different names. - Are you reading from the vault, not the environment?
${secrets.X}resolves from the vault, never fromprocess.env. Use${env.X}for a plain environment variable.
WARNING
If you rotate SECRETS_KEY, existing encrypted values can no longer be decrypted and are skipped. Re-enter your secrets after changing the key.
Scheduled flows are not firing
Scheduled triggers only run when the deployment is wired for them: CRON_SECRET must be set and an external timer must call the tick endpoint once a minute. Without CRON_SECRET the endpoint is fail-closed and schedules never fire. See Scheduled triggers wiring.
Common HTTP status codes at a glance
| Code | Meaning | Where to look |
|---|---|---|
400 | Request did not match declared inputs / missing required field | Validation |
401 | Authentication failed on a protected flow | HTTP triggers |
404 | Unknown path, wrong method, or no Start node | Testing & the trigger URL |
429 | Rate limit hit — slow down and retry | this page |
500 | A node failed and the error was not caught | Error handling |