{"record":{"id":"c48a5056dd91c58a","repo":"zeroclaw-labs/zeroclaw","slug":"gateway-responded-status-detail","errorCode":null,"errorMessage":"Gateway responded {status}: {detail}","messagePattern":"Gateway responded (.+?): (.+?)","errorType":"http","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/main.rs","lineNumber":6975,"sourceCode":"        .map_err(|e| anyhow::Error::msg(format!(\"Failed to connect to gateway: {e}\")))?;\n    let status = resp.status();\n    let out: serde_json::Value = resp.json().await.unwrap_or_default();\n    if status.is_success() {\n        println!(\n            \"{}\",\n            out.get(\"outcome\").and_then(|v| v.as_str()).unwrap_or(\"ok\")\n        );\n        Ok(())\n    } else {\n        // Non-2xx bodies from the SOP routes carry the typed `outcome` label\n        // (e.g. not_waiting -> 404, rejected_self_approval -> 403), not `error`;\n        // prefer it so the operator sees why, falling back to `error`.\n        let detail = out\n            .get(\"outcome\")\n            .and_then(|v| v.as_str())\n            .or_else(|| out.get(\"error\").and_then(|v| v.as_str()))\n            .unwrap_or(\"request failed\");\n        anyhow::bail!(\"Gateway responded {status}: {detail}\");\n    }\n}\n\n#[cfg(feature = \"agent-runtime\")]\nenum PaircodeAction {\n    /// GET the current code; do not mint or revoke anything.\n    Show,\n    /// Issue a fresh code for an additional client; revoke nothing.\n    AddClient,\n    /// Revoke every paired token + clear the registry, then issue a code.\n    RotateAll,\n    /// Revoke a single device's token, then issue a code.\n    RotateDevice(String),\n}\n\n#[cfg(feature = \"agent-runtime\")]\nimpl PaircodeAction {\n    /// True when the action mints a new code (POST), false for `Show` (GET).","sourceCodeStart":6957,"sourceCodeEnd":6993,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/src/main.rs#L6957-L6993","documentation":"A POST to `/admin/sop/approve` or `/admin/sop/deny` came back non-2xx. SOP routes put a typed `outcome` label in the body (e.g. `not_waiting` maps to 404, `rejected_self_approval` to 403); the CLI prefers `outcome` over `error` so the operator sees the precise reason.","triggerScenarios":"`zeroclaw sop approve <run_id>` for a run that already finished or was decided (`not_waiting`), approving your own run while self-approval is rejected (`rejected_self_approval`), an unknown run_id (404), or a daemon-side 5xx.","commonSituations":"Two operators racing to decide the same SOP run; scripts retrying an approve that already succeeded; the run being denied or timing out between `sop pending` and `sop approve`.","solutions":["Re-list waiting runs with `zeroclaw sop pending` and pass a run_id that is still waiting","Treat `not_waiting` immediately after your own successful approve as idempotent completion, not a failure","For `rejected_self_approval`, have a different approver act per the configured approval policy","For 5xx, check the daemon logs before retrying"],"exampleFix":"# before\nzeroclaw sop approve run-123   # run already decided elsewhere\n# after\nzeroclaw sop pending\nzeroclaw sop approve <run_id from the still-waiting list>","handlingStrategy":"try-catch","validationCode":"# refresh the waiting list right before deciding\nzeroclaw sop pending | grep -q \"$run_id\" || { echo \"run $run_id is not waiting\"; exit 2; }","typeGuard":null,"tryCatchPattern":"if ! zeroclaw sop approve \"$run_id\" 2>/tmp/sop_err; then\n  case \"$(cat /tmp/sop_err)\" in\n    *not_waiting*)             echo \"already decided; treating as done\" ;;        # idempotent success\n    *rejected_self_approval*)  assign_second_approver \"$run_id\" ;;\n    *\"Gateway responded 5\"*)   retry_after_backoff ;;\n    *) cat /tmp/sop_err; exit 1 ;;\n  esac\nfi","preventionTips":["Always re-fetch `sop pending` immediately before approve/deny","Make approval scripts idempotent on `not_waiting` instead of failing","Route self-approval-restricted runs to a second operator by design"],"tags":["sop","gateway","http","approval","zeroclaw"],"backgroundTag":"http-error-response","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}