Exit codes and errors

For AI agents: this page is Markdown at https://squiggle.sh/docs/reference/errors.md. Every docs page is listed at https://squiggle.sh/llms.txt, and all of them are one file at https://squiggle.sh/llms-full.txt.

What each squiggle exit code means, so a CI job can act on the number. Plus squiggle explain, which turns an exit code or an error code into the cause and a command that fixes it.

Exit codes

Every squiggle command exits with one of these codes. They don’t change between versions, and squiggle --schema-json lists them too.

CodeMeaning
0Success. There may be warnings.
1The run failed: a flow, a suite, a gate or a diff. Also used for an unexpected error in Squiggle itself, which prints a stack trace.
2A usage error, or a failure Squiggle expected, with a message that says what to do.
3A licence is needed, has expired, or is over its CI limit.
4The --timeout you set ran out.
5No device is available, or another run is using it.
6Needs an agent: an agent: step had no recording that worked, and no agent was connected. No step failed. Pass --needs-agent fail to exit 1 instead.

What CI should do with each

Codes 0, 1 and 6 are results: the flows ran. The others mean they couldn’t run properly, so fix the machine or the job before you trust the result. Pick what happened to see the code and what squiggle explain says about it:

exit0

Green.

Terminal
squiggle explain 0exit 0  success (warnings allowed)

Explain a code

Pass an exit code or an error code to squiggle explain. It prints what went wrong and, when there is one, a command that fixes it. It works without a licence.

Terminal
squiggle explain 5squiggle explain E_STALE_DYLIB

Run squiggle explain on its own to list every code. Add --json to get the same thing as data.

Error codes

CodeWhat happened, and the fix
E_NO_DEVICENo simulator is booted (exit 5). Boot one, or pass --udid to choose one.
E_NOT_INJECTEDsquiggle up launched the app, but Squiggle didn’t attach to it (exit 5). Quit the app completely and run squiggle up again.
E_STALE_DYLIBThe app is running an older copy of Squiggle than this build (exit 5). Quit the app, then run squiggle up.
E_NO_HOSTThe squiggle-host helper that drives the simulator wasn’t found (exit 5). Reinstall Squiggle, or run with --headless.
E_CONNECTThe app never connected on the port the command was waiting on (exit 2). If the message says no app … connected … within 30 s, and this run does not relaunch it, the app isn’t running, often because it crashed, and the run (a bench, a run of several flows, or a report card) doesn’t relaunch it. Run squiggle up, or the flow again with --fresh. Otherwise, run squiggle doctor to check the app is set up and which port it connects to.
E_TIMEOUTThe --timeout ran out (exit 4). Raise it, or give the command less to do.
E_FLOW_PARSEThe flow file isn’t valid YAML, or a step is malformed (exit 2). The message names the line and column. Quote any value that contains #.
E_RUNS_WITHsquiggle flow was given a program whose runWith: names another command, such as squiggle agent branch (exit 2). Run it with the command the message prints.
E_BAD_CHAOS--chaos or --twin named a profile that doesn’t exist, or --twin none (exit 2). The profiles are slow, flaky, truncated and offline-midstep; --chaos also takes none, and --twin takes all.
E_NO_STUBS--stubs named a run that isn’t in .squiggle/runs, or one that made no requests (exit 2). Run the flow once with --capture-net, and pass the run id its footer prints.
E_BAD_RUN_COUNT--fuzz-max or --race-max wasn’t a whole number of runs, 1 or more (exit 2).
E_TWIN_CLASH--twin, --fuzz or --cache-twins was combined with a flag that also chooses the network or the starting state, such as --chaos, --stubs or --race (exit 2). Pass one of them.
E_RACE_CLASH--race was combined with --chaos or --stubs (exit 2). --race sets every request’s delay itself; drop the other flag.
E_BAD_CLIFF--cliff wasn’t VAR=lo..hi, such as N=10..800 (exit 2).
E_BAD_TUNE_WEIGHTS--tune-weights named a term other than dropped, blank or ms, or a weight that isn’t a number ≥ 0 (exit 2).
E_TUNE_CLASH--tune was combined with --fresh (exit 2). A relaunch puts each tunable back to its default; drop --fresh.
E_BISECT_STATE_CLASH--bisect-state was combined with a flag that also chooses what each run starts from, such as --fresh, --cache-twins, --tune or --twin (exit 2). Pass one of them.
E_MATRIX_PLATFORM--matrix was run against a Mac app (exit 2). Its cells are simulator settings, so it needs an iOS simulator.
E_BISECT_NATIVEA commit in the squiggle bisect range changes native code or a dependency, which Metro can’t serve (exit 2). Bisect from after that commit with --good, or rebuild and bisect across it by hand.
E_BISECT_USAGEsquiggle bisect got a range it can’t use: --good isn’t an ancestor of --bad, or the range is empty (exit 2).
E_BAKEOFF_USAGEsquiggle bakeoff got an empty --against or a ref that isn’t a commit, or found no app.json (exit 2). Pass --app-dir when the Expo app isn’t at the project root.
E_BAKEOFF_NATIVEA squiggle bakeoff branch differs from your checkout in native code or a dependency, which Metro can’t serve (exit 2). Compare branches that differ only in JavaScript.
E_BAKEOFF_NO_RUNsquiggle bakeoff started the flow on a revision, but it never ran, for example because the app wasn’t running or the flow name is wrong (exit 1). The error above it says why; fix that and run again.
E_CONTRACTS_PRsquiggle contracts propose --pr couldn’t commit, push or open the pull request; the message shows what git or gh said (exit 1). Run it with --write instead and commit the flows yourself.
E_NO_AGENTsquiggle motion found no Squiggle agent in the app (exit 5). Run squiggle up.
E_MOTION_CAPTUREsquiggle motion couldn’t record the view around the tap, for example because the control to tap wasn’t on screen (exit 1).
E_MOTION_MATCHThe file given to squiggle motion --match couldn’t be read (exit 2). It takes the output of an earlier squiggle motion --json.
E_PROBE_RULEA squiggle probe rule isn’t one (exit 2): it needs an input, a comparison and a number, such as render.max >= 30, and the input must be one that squiggle probe inputs lists.
E_PROBE_UNSUPPORTEDThe app doesn’t take probes (exit 5): it is a release build, which never runs one, or its Squiggle SDK is older than probes.
E_PROBE_REFUSEDThe app refused the probe and said why (exit 2), for example a range wider than the input’s, more than 256 instructions in one probe, or more than eight probes at once.
E_PROBE_NO_FIRINGSsquiggle probe export found no recorded firings for that id (exit 2). Run the probe with squiggle probe when first, with the same rules and --id.
E_PROBE_MISMATCHThe rules given to squiggle probe export aren’t the ones the probe ran with (exit 2): re-running them over the recorded firings gives different answers. Pass the same rules, --any and --component as the probe used.
E_LICENSE_REQUIREDNo licence or trial on this Mac (exit 3). Run squiggle activate --trial, or activate a key.
E_LICENSE_EXPIREDThe trial or licence has ended (exit 3). Run squiggle activate with a current key.
E_CI_LIMITToo many CI runners are using this licence at once (exit 3). Wait for one to finish, or see your plan’s limit with squiggle license.

For problems that don’t produce an error code, see Troubleshooting.