Weir docsv4
View as Markdown

Troubleshooting

Permalink to Troubleshooting

Each entry is one failure an unassisted integration actually hits, with the symptom, the cause, and the fix. They are drawn from real first-run friction, not hypotheticals.

weir_app_doctor reports the sdk-use check as failed

Permalink to weir_app_doctor reports the sdk-use check as failed

Symptom. weir app-doctor --appRoot . returns ready: false with a failed flow:<id>:sdk-use check: "adapter exists but no Weir.configure/present/WeirView call was found."

Cause. The integrationFile declared in weir/app.json exists but the doctor cannot find one of the native entry-point names it knows. A stub should fail, but a pass only proves a matching symbol exists; it does not prove registry setup or a working presentation.

Fix. For SwiftUI, verify the file really registers components, installs the generated registry, calls Weir.configure, and presents WeirFlowView/Weir.present with a v4 config root. For RN/Expo, the doctor recognizes WeirCore.fetchConfig and <WeirFlow>; also verify WeirRegistry.setGeneratedRegistry and the full device journey. For native Compose, verify the real WeirFlow journey rather than treating a source-symbol match as device evidence.

weir_app_doctor refuses before running any check

Permalink to weir_app_doctor refuses before running any check

Symptom. The tool errors on the config check and runs nothing else.

Cause. weir/app.json is missing, unparseable, or fails the schema. The doctor needs a valid config before it can check anything.

Fix. Confirm the file exists at the --appRoot you passed and inspect the validation issues. The current parser expects version: 1, platform ios|android|reactNative, a non-empty flows array, and one of the documented delivery.updateConfig values. Do not change a valid app contract merely to silence a different check; fix the named path or field and rerun doctor.

weir_app_doctor reports baseline-config or baseline-freshness

Permalink to weir_app_doctor reports baseline-config or baseline-freshness

Symptom. The doctor reports a missing, invalid, or stale native baseline config or asset.

Cause. The directory declared by flows[].baselineBundle has no config.json, its flow id does not match, its normalized bytes differ from the current source spec, or a referenced customAssets[].path file is missing or stale.

Edit → verify loop. Edit weir/flows/<flowId>.json, then run weir app-doctor --appRoot .. The baseline-freshness check now fails because the embedded config no longer matches the flow. Run weir embed --appRoot . --flowId <flowId> to re-embed it, then re-run weir app-doctor --appRoot .; the check passes once the baseline matches again.

Fix. Run weir embed --appRoot . --flowId <id> to rebuild the native baseline from the authoritative app contract, rerun doctor, then inspect the built app and prove the packaged config and assets render on a device. Do not add index.html or manifest.json; those are retired browser-preview artifacts, not native input.

weir_conform looks hung

Permalink to weir_conform looks hung

Symptom. weir conform prints nothing for minutes; a short command timeout kills it.

Cause. Conform runs a real headless-browser persona walk. Expected runtime is about 3–5 minutes for a ten-screen flow. It is progressing, not hung.

Fix. Do not set a timeout under about six minutes. Watch stderr — conform streams screen N/total: <screenId> ok per screen as it walks, so you can confirm progress. It exits 0 only when every contract check passes.

weir_conform fails on the event stream or a variable

Permalink to weir_conform fails on the event stream or a variable

Symptom. Conform exits non-zero reporting an event-stream mismatch, an unset declared variable, or a native-feel check.

Cause. The browser-preview artifact's behavior diverges from what the spec implies — a screen the walk cannot complete, a variable no screen sets, a literal currency string instead of a real products.list value, or network on the paint path.

Fix. Run weir walk first (see Sandbox preview & branch verification) and read walk-report.json: reachedComplete must be true and variables must have every declared variable set. Fix the spec so every variable is written on every path and every persona reaches complete(), then re-run conform. This proves the authoring contract, not the native app renderer; follow it with SwiftUI/RN component and device tests.

weir_release fails — tell a credential error from a build error

Permalink to weir_release fails — tell a credential error from a build error

Symptom. weir release fails and it is unclear whether the flow or the server is at fault.

Cause. weir release does two different things that fail two different ways: the local build/conform gate, and the publish call to the delivery API.

Fix. Separate them. Run weir release --appRoot . --flowId onboarding --dryRun first — the dry run does the whole gate except the API call and needs no WEIR_API_URL/WEIR_API_TOKEN. If the dry run fails, it is a build/conform problem (fix the spec). If the dry run passes but the real release fails, it is a delivery problem: check the server is reachable, and that WEIR_API_TOKEN matches this app's id if the server enforces tokens. If no operator has issued a token yet, stop after the dry run — the server configuration is the token-issuance authority. For fully local runs you need neither variable; see Run everything locally.

The kill switch does not revert the app to native

Permalink to The kill switch does not revert the app to native

Symptom. weir_onboarding_enabled is off in Remote Config, but the app still shows (or fails to show) the Weir flow.

Cause. The kill switch lives on Firebase Remote Config by design, and its keys must match exactly. A mismatched or missing weir_onboarding_enabled / weir_manifest_url / weir_manifest_public_key / weir_ingest_url / weir_ingest_token breaks the revert path.

Fix. Confirm all five Remote Config keys are present and spelled exactly as above, and that the app reads them at runtime — not from weir/app.json, which holds no secrets or endpoints. With the flag off, the app must return to nativeFallback without the delivery origin being reachable at all. If the flag is on but delivery is unavailable, the app-embedded v4 config is the SDK's offline config tier. See Concepts → Kill switch.

Android app: a debug flag override never turns the flow on

Permalink to Android app: a debug flag override never turns the flow on

Symptom. You set an environment variable to force weir_onboarding_enabled on for a local proof, but the app ignores it.

Cause. An am-launched Android app process (how adb and the launcher start your app) does not inherit adb-set environment variables, so System.getenv(...) can never be toggled from adb on a device or emulator.

Fix. If the host app deliberately implements this testing seam, use an adb-settable system property, which the app process does see. Wire a debug-only override that reads debug.weir_onboarding, then force it on with:

adb shell setprop debug.weir_onboarding true

This is host-app code, not a promise of a supported native Compose package. Rebooting the emulator clears debug props, which is a quick way to confirm the app's override no longer wins.

iOS: a local http://localhost fetch fails silently

Permalink to iOS: a local http://localhost fetch fails silently

Symptom. The iOS demo app points at http://localhost:8787 but never loads the config, with no clear error.

Cause. Default App Transport Security blocks plaintext http://. The demo Info.plist has no NSAppTransportSecurity exception, so the request is denied before it leaves the app.

Fix. Add an NSExceptionDomains block for localhost and 127.0.0.1 (with NSExceptionAllowsInsecureHTTPLoads) to the demo's Info.plist. Android already permits cleartext for local hosts and needs no change. See Run everything locally.

The dashboard shows production data (or nothing) instead of your local server

Permalink to The dashboard shows production data (or nothing) instead of your local server

Symptom. You run the dashboard against a local API, but it shows the live box's data, or empty views.

Cause. The dashboard's API base already defaults to http://localhost:8787, so this usually means something else is overriding it: a stale localStorage override from a previous session (under weir_dashboard_api_base), or VITE_API_BASE was set to the live API at build time (as a production build's own .env.production intentionally does).

Fix. Check for a stale override first: in the running app, open "Advanced: sign in with a bearer token" and look at the "API base URL override (local dev only)" field — clear it or set it to http://localhost:8787. If you built with VITE_API_BASE set, rebuild without it (or set it to http://localhost:8787 explicitly). See Run everything locally.

Generated from this repo's source at build time — packages/mcp/src/tools/index.ts and packages/spec/src/events.ts are the ground truth for the tool and event tables above. llms-full.txt