Decision tree
| Symptom | Most likely cause | Start here |
|---|---|---|
zombiectl install --from exits non-zero | Frontmatter validation failed | §1 Install rejected |
| Upstream says it sent the webhook, agent didn’t wake | Signature mismatch or wrong URL | §2 Webhook delivered but agent silent |
| Agent woke, run failed before producing output | Credential, network, or tool error | §3 Run opens then fails |
| Run produces a result but it’s wrong | SKILL.md prose or memory issue | §4 Run completes but output is wrong |
Run terminates with budget_breach | daily_dollars / monthly_dollars ceiling hit | §5 Budget breach |
zombiectl itself is broken (auth, network) | Local config or platform reachability | §6 zombiectl can’t reach the platform |
1. Install rejected
zombiectl install --from <path> exited with code 2. The platform parsed your SKILL.md + TRIGGER.md and rejected them.
--json output carries the wire error code:
| Wire code | Cause | Fix |
|---|---|---|
UZ-ZMB-008 | TRIGGER.md config_json fails schema validation | Re-read Authoring §x-usezombie: subkeys. Common: a runtime key (tools, credentials, network) at the top level instead of nested under x-usezombie:. |
UZ-ZMB-011 | SKILL.md and TRIGGER.md disagree on top-level name: | Make both files’ name: value identical. |
UZ-VAULT-001 | Credential data body is empty / not a JSON object | The error is from a prior credential add call, not from install itself. Re-run zombiectl credential add <name> --data=@- with a non-empty JSON object. |
UZ- prefix.
Local validation tip: the parser the platform uses is the same one zombiectl install --from runs — there’s no separate lint command. To catch schema errors before committing, run zombiectl install --from <path> --json and read the structured error output. Note the call still uploads on success; there is no --validate-only flag.
2. Webhook delivered but agent silent
The upstream provider says it fired the webhook, your activity stream shows nothing.Diagnostic
| Pattern | Meaning |
|---|---|
| Zero events in the window | Request never reached the platform (DNS, firewall, wrong URL on the upstream side). |
| Events with rejection metadata, not run opens | Signature verification failed. |
Events but actor: webhook:unknown | Source label is missing or the signature block in TRIGGER.md doesn’t match the upstream’s actual headers. |
Wire codes returned to the upstream
If the upstream itself shows a non-2xx response, the body carries one of:| Wire code | HTTP | What to check |
|---|---|---|
UZ-WH-001 | 404 | URL is wrong. The path is https://api.usezombie.com/v1/webhooks/{zombie_id}/{source} — verify the ID matches zombiectl status. |
UZ-WH-002 | 400 | Request body is malformed JSON or empty. |
UZ-WH-003 | 403 | Agent is paused or killed. zombiectl status will show the state; re-install with zombiectl install --from <path>. |
UZ-WH-010 | 401 | HMAC signature verification failed. The shared secret in your vault doesn’t match the one configured at the upstream. Rotate per Quickstart → Verify the registered webhook. |
UZ-WH-011 | 401 | Replay-window violation — request timestamp is older than 5 minutes. Sender clock skew is the usual culprit. |
UZ-WH-020 | 401 | No webhook credential configured for this agent’s source. The secret_ref in TRIGGER.md either isn’t set or points at a vault key that doesn’t exist. Run zombiectl credential list to confirm; add with zombiectl credential add <source> --data=@-. |
UZ-WH-030 | 413 | Payload exceeds the 1 MiB ingest limit. The upstream is sending too much; filter or trim the event body before forwarding. |
Common signature config mistakes
github, slack, linear), don’t set header and prefix manually — the registry fills those. See Webhooks → Natively normalized providers.
3. Run opens then fails
The webhook landed and a run opened, but it terminated before producing output. The activity stream shows the run, then an error event.Diagnostic
| Wire code | Cause | Fix |
|---|---|---|
UZ-ZMB-003 | A required vault credential is absent | The credential name in TRIGGER.md credentials: doesn’t exist in the workspace vault. zombiectl credential list to confirm; zombiectl credential add <name> --data=@- to add. |
UZ-ZMB-002 | Agent timeout | The model didn’t return within the per-event ceiling. Often a sign the prompt is too large or the model is overwhelmed. Tighten SKILL.md or check tool_window in Context lifecycle. |
UZ-MEM-003 | Memory backend unavailable | Transient. Re-trigger; if persistent, file an issue. |
UZ-MEM-001 | Memory scope denied | The agent tried to read another agent’s memory. Check the key derivation in SKILL.md — keys are agent-scoped. |
Tool-related failures don’t surface as wire codes. When a
tools: entry has a typo, the runner logs UZ-TOOL-005 at warn level and silently skips it. When the agent tries to invoke a tool that isn’t in its resolved set, NullClaw returns a “no such tool” message in the activity stream rather than emitting UZ-TOOL-004 to a caller. Both UZ-TOOL-* codes exist in the registry (see Error codes → Tool) but in v2 today the diagnostic signal is the activity-stream entry, not a wire response. Audit zombiectl logs <zombie_id> for the actual error text. See Tools catalogue → Validation.Network allowlist drops
If the agent callshttp_request against a host not in network.allow:, the call fails silently from the agent’s perspective (the tool returns an error, the agent reasons about it). The drop appears in the activity stream as a tool-error event with the blocked hostname. Add the host to network.allow: in TRIGGER.md and re-install.
4. Run completes but output is wrong
The hardest class of failure. Run exits cleanly, the diagnosis posts to Slack, but the diagnosis is wrong, off-topic, or omits something it should have said.Diagnostic
SKILL.md told it to do:
| Symptom | Likely cause |
|---|---|
| Agent skipped a step you specified | Step is unclear, ambiguous, or buried mid-paragraph. Move it to a numbered list at the top. |
| Agent called the wrong endpoint | SKILL.md named the endpoint without context. Add the full URL or the credential name explicitly. |
| Agent hallucinated a value | Source data wasn’t in the event payload or a memory recall. Don’t ask the agent to invent — surface every input explicitly. |
| Agent re-asked for info you already gave it | memory_recall isn’t being called at the start of the run. Audit your SKILL.md — recall must happen before reasoning. See Memory. |
| Agent posted twice | Webhook delivery is at-least-once. Add a dedupe step using the upstream event_id in memory_recall/memory_store. |
Iterating on prose
SKILL.md is a prompt. The fastest debug loop is zombiectl steer:
SKILL.md, zombiectl install --from ., re-steer. The next event uses the new prose — no redeploy.
5. Budget breach
Run terminated withUZ-ZMB-001. The daily_dollars or monthly_dollars ceiling in TRIGGER.md was hit.
- Per-agent (
TRIGGER.mdbudget.daily_dollars/monthly_dollars) — terminates this agent’s runs until the rolling window resets. Raise the value, re-install. - Tenant wallet — every workspace’s runs debit the same pool. When it hits zero, all runs across all workspaces stop. Top up at
app.usezombie.com/billing. See Billing → Budgets.
tokens or wall_ms fields), and consider tightening SKILL.md or splitting the work across multiple smaller agents.
6. zombiectl can’t reach the platform
Anything that affects every command — login fails,status returns errors, install 401s.
Diagnostic
| Check | Failure means |
|---|---|
server_reachable | API is unreachable from your machine. Check your network. The base URL is https://api.usezombie.com (override with --api or ZOMBIE_API_URL). |
workspace_selected | Local config has no current_workspace_id. Run zombiectl workspace add [name] (creates + activates) or workspace use <id> (activates an existing one). |
workspace_binding_valid | Auth token doesn’t have access to the selected workspace. Either the token expired (re-run zombiectl login) or the workspace was deleted on the server. |
--json for the structured envelope: { ok: bool, api_url: string, checks: [{ name, ok, detail }] }.
Auth resolution order
Ifzombiectl keeps acting unauthenticated, your token might be coming from somewhere unexpected. Resolution order, highest priority first:
--token <value>flagZOMBIE_TOKENenvironment variable- Stored credentials at
~/.config/zombiectl/credentials(written byzombiectl login)
ZOMBIE_TOKEN if you’ve been running CI scripts that exported it; otherwise it overrides whatever zombiectl login wrote.
When to escalate
Two paths, depending on whether you want a fix or a faster sanity-check. Fast: ask in Discord. Best for “is this a known issue?”, “is this expected?”, or anything where you need a human eye in minutes rather than hours. Design partners and the core team hang out there. Durable: file an issue at github.com/usezombie/usezombie/issues. Best when the problem is reproducible, blocks shipping, or hits any of:- Diagnostic returns no error but the symptom persists across multiple triggers.
- A
UZ-INTERNAL-*orUZ-AUTH-004(auth service unavailable) keeps firing. zombiectl doctorpasses but operations still fail.
request_id from the --json error envelope, the wire code, and a recent timestamp — those uniquely identify the request server-side.
See also
- Error codes — full registry of
UZ-*codes. - Webhooks — signature config reference.
- Authoring —
SKILL.md/TRIGGER.mdschema. - Context lifecycle — when long runs get continued or escalated.