Troubleshooting¶
This guide covers the most common ForgeOS failures during local development, CI, and agent-driven edits. Forge diagnostics are designed to be machine-readable — prefer --json flags when debugging with agents.
First response checklist¶
When something fails, run this sequence:
forge status --json
forge dev --once --json
forge doctor
forge generate --check
forge check --json
forge verify --standard --json
For Windows-specific path and shell issues:
forge doctor windows --json
forge setup windows --yes
Diagnostic commands¶
| Command | Use when |
|---|---|
forge status --json |
Compact project health, handoff state, and next actions |
forge handoff --json |
Switching agents, resuming work, or creating a compact work brief |
forge dev --once --json |
Single-pass snapshot: drift, routes, doctor, impact |
forge doctor |
Missing contract files, stale generated output |
forge check --json |
Guard violations, secret rules, AI/query usage |
forge agent print-context --json |
Agent-facing generated context pack |
forge inspect all --json |
Compact aggregate inspection |
forge inspect all --full --json |
Deep project dump when compact context is not enough |
forge inspect frontend --json |
Route/binding/capability-map issues |
forge inspect runtime-matrix --json |
Package context compatibility |
forge repair diagnose --json |
Structured failure analysis |
forge telemetry inspect <traceId> |
Policy/runtime errors with trace id |
Human-readable playbooks also live in:
AGENTS.mdsrc/forge/_generated/operationPlaybooks.md
Error map¶
| Symptom or code | First command | Likely fix |
|---|---|---|
| Generated files are stale | forge generate --check |
Run forge generate, then review generated drift. |
FORGE_GUARD_VIOLATION |
forge check --json |
Move network/secret/AI work to action, workflow, endpoint, or server code. |
FORGE_AI_FORBIDDEN_CONTEXT |
forge ai check --json |
Move model calls out of command, query, or liveQuery. |
FORGE_POLICY_DENIED |
forge policy simulate <policy> --role <role> --json |
Fix caller role, tenant scope, or policy declaration. |
| LiveQuery stale data | forge live status --json |
Check durable invalidations, tenant dependencies, and worker health. |
| Frontend route not connected | forge inspect capabilities --json |
Use generated hooks and the local web/**/lib/forge.ts bridge. |
| Windows app picker opens for Bun | forge doctor windows --json |
Set a safe Bun path or use the Node CLI path. |
| Tests hang or run too long | forge verify --standard --script-timeout-ms 120000 --json |
Use impact tests first; reserve strict verification for handoff. |
Stale global forge in framework checkout |
node bin/forge.mjs status --json |
Use the source-tree entrypoint while maintaining ForgeOS; use global forge only for package smoke. |
| Codex hooks waiting for approval | forge agent hooks status --target codex --json |
Approve the Codex Desktop hook prompt, continue a Codex session, then rerun status. |
| DeltaDB or PGlite busy | forge delta status --json |
Wait for the owning pid/command or inspect .forge/delta/delta.lock before repair. |
| Studio preview points at Studio | forge studio doctor . --preview-port 5174 --target codex --json |
Use the target app preview on 5174; avoid self-preview on 5173. |
CLI entrypoint mismatch¶
Symptom: A ForgeOS maintainer command shows old help text, generated AGENTS mention unavailable commands, or forge verify behaves differently from the source tree.
Cause: The global forge binary can lag behind the framework checkout.
Fix in generated apps:
forge status --json
forge verify --smoke
Fix in the ForgeOS framework checkout:
node bin/forge.mjs status --json
node bin/forge.mjs verify framework
Use global forge from this repository only when intentionally validating the installed package path.
Stale generated artifacts¶
Symptom: forge doctor reports generated artifacts are stale, or forge generate --check fails.
Cause: Source changed but _generated/ or forge.lock was not regenerated.
Fix:
forge generate
forge generate --check # confirm clean
git status # review generated changes
Template apps often gitignore _generated/ — run forge generate after clone before verify.
FORGE_GUARD_VIOLATION¶
Symptom: forge check error like:
'stripe' is not allowed in 'command' context
Cause: A package import violates the runtime matrix (network SDK in a command, query, or liveQuery).
Fix options:
- Move logic to an action (recommended) — see Payments.
- Run extract-action codemod — see Codemods.
- Use type-only imports in commands when you only need types:
typescript
import type Stripe from "stripe"; // allowed
- Inspect matrix to confirm allowed contexts:
bash
forge inspect runtime-matrix --json
forge repair diagnose --diagnostic FORGE_GUARD_VIOLATION --json
Common mistakes:
| Mistake | Fix |
|---|---|
| Stripe/Payment SDK in command | Action + ctx.emit |
process.env.STRIPE_SECRET_KEY in app code |
ctx.secrets or generated adapter |
| PostHog server SDK in query | Move to action or server module |
| Importing action code into command | Keep dependency direction command → emit only |
Secret errors¶
Symptom: Missing secret diagnostics, auth failures, or --strict-secrets check failures.
Fix:
forge inspect secrets --json
- Add values to
.env(local) or deployment secret store (production). - Register secret names in config; never commit values.
- After
forge add stripe, expectSTRIPE_SECRET_KEYandSTRIPE_WEBHOOK_SECRET.
Run strict check:
forge check --strict-secrets --json
forge add failures¶
| failureKind | Meaning | Fix |
|---|---|---|
unknown_alias |
Unsupported forge add target |
Use stripe, posthog, sentry, zod, or ai |
install_failed |
npm install error | Check network, lockfile, permissions; try --allow-scripts |
lock_integrity |
forge.lock mismatch |
forge generate, resolve merge conflicts |
write_failed |
Emit error | Permissions, disk space |
Always inspect JSON output:
forge add stripe --json
On failure, Forge restores version-controlled files from the pre-add snapshot.
verify failures¶
Symptom: forge verify --standard or --strict exits non-zero.
Steps:
forge verify --standard --json
# Read steps[].failureKind and diagnostics[]
forge test run --changed --json
forge repair diagnose --from-last-test-run --json
Inspect last test output:
.forge/test-runs/last.json
Skip flags (narrow debugging only):
forge verify --standard --skip-tests
forge verify --standard --skip-typecheck
For release handoff, fix root cause — do not skip gates permanently.
forge verify is app-scoped. It should not run ForgeOS framework tests in ordinary generated apps. Framework maintainers must opt into the internal gate with node bin/forge.mjs verify framework.
Agent hooks approval and stale events¶
Symptom: forge agent hooks smoke --target codex --json passes, but forge agent hooks status --target codex --json reports approvalRequired, waiting-for-user-trust, missing native signals, or stale hook signals.
Cause: The smoke canary proves ForgeOS ingestion and DeltaDB memory. Codex Desktop still has a separate trust prompt before it executes native hook files. Hook events are queued in .forge/agent/events.ndjson and drained from checkpoints, so old canary events do not prove that Codex has approved and emitted a fresh native event.
Fix:
forge agent hooks status --target codex --json
forge agent hooks smoke --target codex --json
Approve the Codex Desktop hook prompt, continue or start a Codex session in the same workspace, then rerun status. If the status remains stale, inspect the JSON approvalStatus, nativeSignals, canarySignals, and suggested commands before reinstalling hooks.
DeltaDB and PGlite busy¶
Symptom: A mutating agent-memory, timeline, session, or repair command returns FORGE_DELTA_BUSY, or Studio reports DeltaDB/PGlite is active.
Cause: Another local ForgeOS or external-agent process owns the PGlite writer lock. Read-only commands should still work; writer operations fail fast instead of hanging.
Fix:
forge delta status --json
forge agent hooks status --target codex --json
Read the JSON busy block for lock path, pid, process-alive signal, lock age, cwd, and command. Wait for the owning command to finish when it is alive. If the process is gone, inspect .forge/delta/delta.lock before running repair.
Studio target preview issues¶
Symptom: Studio opens an iframe of itself, starts duplicate target previews, or reports preview state that does not match the app.
Cause: Studio reserves 127.0.0.1:5173 for the observer app. The target app should normally run on preview port 5174. ForgeOS records target preview state in .forge/studio/preview.json and reuses a live matching process instead of starting another one.
Fix:
forge studio doctor . --preview-port 5174 --target codex --json
forge studio open . --preview-port 5174 --target codex --json
If another tool owns preview startup, pass --no-start. If the recorded preview process has exited, rerun studio open; stale preview state is removed before a new start attempt. .forge/studio/*.json files are local operational state and should not be committed.
Repair workflow¶
When checks fail, do not guess. Use the repair loop:
forge test run --changed --timeout-ms 120000 --json
forge repair diagnose --from-last-test-run --json
forge repair plan --from-last-test-run --write
forge repair apply <repair-id> --yes # high confidence only
forge verify --changed
forge verify --strict
diagnose returns:
failureKind— category of failurelikelyCause— human-readable explanationsuggestedRepairs— ranked fixes with confidencesuggestedCommands— CLI next steps
Apply only high-confidence repairs automatically. Review medium/low confidence changes manually.
Other diagnose sources:
forge repair diagnose --from-last-ui-run --json
forge repair diagnose --diagnostic FORGE_GUARD_VIOLATION --json
forge repair diagnose --trace <traceId> --json
forge repair diagnose --outbox-delivery <id> --json
Outbox and worker issues¶
Symptom: Events emitted but side effects never run (emails, Stripe charges, etc.).
Checks:
forge dev # starts worker with local stack
forge worker --once # process outbox manually
forge inspect subscriptions --json
Ensure:
- Command called
await ctx.emit(...)inside the handler. - Action subscribes to the same event name.
- Worker is running in dev/production.
- Database reachable (outbox tables
_forge_outbox,_forge_outbox_deliveries).
Frontend wiring issues¶
Symptom: Routes missing, capability-map warnings, dev auth problems.
forge dev --once --json
forge inspect frontend --json
forge inspect capabilities --json
Common issues:
| Issue | Hint |
|---|---|
web/ exists but no frontend graph |
Run forge generate; check web/ layout |
| Missing bridge files | Template expects generated client bindings |
| devAuth tenantId warning | Use UUID-like tenant id when DB tenant columns are uuid |
Policy and auth errors¶
Symptom: 403 responses, policy denial in UI.
forge policy simulate <policyName> --role <role> --json
forge telemetry inspect <traceId>
Capture traceId from API response or browser network tab.
Production uses JWT/OIDC; local dev may use dev-headers mode. See Security and Data and generated authConfig.json.
LiveQuery stale or not updating¶
Symptom: UI subscribed with useLiveQuery does not refresh after a command write.
Cause: Invalidation not recorded, worker not running, wrong tenant, or client not resuming SSE.
Fix:
forge live status --json
forge live invalidations list --json
forge live debug <subscriptionId> --json
Checklist:
- Command performed a transactional write that should invalidate the table.
- Outbox worker is running (
forge devincludes worker by default). - Invalidation rows exist in
_forge_live_invalidationswith revision newer than client snapshot. - Client reconnects with
Last-Event-IDor?lastRevision=after disconnect.
See Frontend — LiveQuery.
Repair loop¶
Symptom: Tests or verify failed; unsure what to fix.
forge do fix --json
forge test run --changed --timeout-ms 120000 --json
forge repair diagnose --from-last-test-run --json
forge repair plan --from-last-test-run --write
Apply only high-confidence suggested repairs automatically. Re-run:
forge verify --changed
forge verify --strict
See Testing and Repair.
Windows-specific issues¶
forge doctor windows --json
forge setup windows --yes --json
Typical fixes:
- Bun/Node path resolution
.cmdshim spawning (field tests and subprocess CLI)- Line endings and lockfile tooling
CI runs multi-OS matrix (ubuntu, windows, macos) on Node 22 and 24.
Generated drift in CI¶
Symptom: CI fails on forge generate --check or external quickstart job.
Fix locally:
forge generate
git diff src/forge/_generated/
Commit regenerated artifacts if your project tracks them, or ensure CI runs generate before check (template apps often ignore _generated/ in git).
npm / field test failures¶
When validating the published package:
npm run field:test -- \
--package-managers npm \
--templates minimal-web \
--forge-spec "npm:forgeos@alpha" \
--install \
--json
See Field Testing for the full matrix workflow.
AI and agent errors¶
Symptom: forge check reports FORGE_AI_FORBIDDEN_CONTEXT.
Cause: ctx.ai or ctx.agent was used in a forbidden context (command, query, liveQuery, client, shared, or edge).
Fix:
- Move AI logic to an action or workflow step after commit.
- Keep the command fast: write to
ctx.dbandctx.emit(...). - Re-run:
bash
forge check --json
forge inspect ai --json
See AI — Runtime Rule and Runtime Model.
Symptom: FORGE_AI_SECRET_MISSING or forge ai check reports missing secrets.
Fix:
forge add ai
forge ai check --json
Configure OPENAI_API_KEY, ANTHROPIC_API_KEY, or AI_GATEWAY_API_KEY in .env, then restart dev.
Symptom: FORGE_AI_MODEL_MISSING or FORGE_AI_DYNAMIC_PROVIDER.
Cause: Missing static model: literal or dynamic provider: selection in source.
Fix: Use static string literals for provider and model so the compiler can register calls in aiRegistry.json.
Symptom: Agent run fails in dev or returns 403.
Fix:
forge dev --once --json
curl -X POST "$FORGE_URL/ai/agents/run" \
-H "Content-Type: application/json" \
-H "x-forge-user-id: dev-user" \
-H "x-forge-tenant-id: dev-tenant" \
-H "x-forge-role: owner" \
-d '{"prompt":"hello","maxSteps":4}'
Ensure dev auth headers match your app's auth mode. Inspect tool availability:
forge ai tools --json
forge inspect agent-tools --json
Symptom: Need to debug a completed agent run.
forge ai trace <traceId> --json
Use the traceId from the API response header x-forge-trace-id or telemetry events.
Symptom: Unexpected provider charges during local development.
Fix: Use mock mode:
FORGE_MOCK_AI=1 forge dev
forge ai test --provider openai --model gpt-4o-mini --prompt "ping" --mock
Symptom: Chat UI executes a write tool without confirmation.
Cause: Command auto-tools require approval; the UI must call addToolApprovalResponse (AI SDK UI) before Forge executes a command tool.
Error code reference¶
| Code | Area | Typical fix |
|---|---|---|
FORGE_GUARD_VIOLATION |
Import guards | Move code to action; extract-action |
FORGE_UNKNOWN_ALIAS |
forge add | Use supported alias |
FORGE_ADD_INSTALL_FAILED |
forge add | Fix npm install |
FORGE_LOCK_INTEGRITY |
generate/add | Regenerate; fix lock conflicts |
FORGE_REFACTOR_PATCH_UNSAFE |
codemod | Adjust source shape; dry-run again |
FORGE_REFACTOR_TARGET_NOT_FOUND |
codemod | Check names/paths |
FORGE_VERIFY_TESTS |
verify | forge test run; repair diagnose |
FORGE_DRY_RUN_FALLBACK |
forge add dry-run | Informational; plan still returned |
FORGE_AI_FORBIDDEN_CONTEXT |
AI placement | Move AI to action/workflow; see AI |
FORGE_AI_SECRET_MISSING |
AI secrets | Configure provider keys; forge ai check |
FORGE_AI_MODEL_MISSING |
AI registry | Add static model: literal |
FORGE_AI_DYNAMIC_PROVIDER |
AI registry | Prefer static provider: literal |
FORGE_AI_GENERATION_FAILED |
AI runtime | Check secrets, model name, provider status |
Full diagnostic codes appear in CLI JSON under errors[].code with fixHint and suggestedCommands.
forge check --json also lifts diagnostic suggestedCommands into top-level
nextActions, so agents can usually move from the failing check directly to the
right repair, inspect, or refactor command.
Escalation path¶
forge dev --once --json— collect snapshotforge repair diagnose ... --json— structured analysisforge inspect all --full --json— full contract reviewforge verify --strict— confirm fix before handoff
For framework bugs, include JSON output and steps to reproduce when opening an issue on the repository.