zeroclaw-labs/zeroclaw · error · anyhow::Error
`zeroclaw sop approve/deny/pending` requires the agent-runti
Error message
`zeroclaw sop approve/deny/pending` requires the agent-runtime build (the gateway client)
What it means
`zeroclaw sop approve|deny|pending` must reach the running daemon's `/admin/sop/*` endpoints, and the gateway HTTP client plus `gateway_admin_url` compile only behind the `agent-runtime` cargo feature. In builds without it, `sop_admin_dispatch` bails immediately instead of failing at connect time. Local SOP verbs (list/validate/show) still work because they never touch the gateway.
Source
Thrown at src/main.rs:6848
Err(anyhow::Error::msg(format!(
"Failed to connect to gateway: {e}"
)))
}
}
}
/// Dispatch the gateway-backed SOP verbs. Requires the `agent-runtime` build (the
/// gateway HTTP client + `gateway_admin_url` live behind it, like `shutdown_gateway`);
/// without it these verbs cannot reach the daemon, so they error clearly.
async fn sop_admin_dispatch(cmd: SopCommands, config: &crate::config::Config) -> Result<()> {
#[cfg(feature = "agent-runtime")]
{
sop_admin_request(cmd, config).await
}
#[cfg(not(feature = "agent-runtime"))]
{
let _ = (cmd, config);
anyhow::bail!(
"`zeroclaw sop approve/deny/pending` requires the agent-runtime build (the gateway client)"
)
}
}
/// CLI -> daemon dispatch for the out-of-band SOP approval verbs (EPIC C, C8).
/// Posts to `/admin/sop/*` on the running gateway (mirrors `shutdown_gateway`);
/// never builds a throwaway local engine, which cannot see the daemon's runs.
#[cfg(feature = "agent-runtime")]
async fn sop_admin_request(cmd: SopCommands, config: &crate::config::Config) -> Result<()> {
let host = config.gateway.host.clone();
let port = config.gateway.port;
let prefix = config.gateway.path_prefix.as_deref();
let client = reqwest::Client::new();
match cmd {
SopCommands::Pending => {
let url = gateway_admin_url(&host, port, prefix, "/admin/sop/pending");
let resp = clientView on GitHub (pinned to 88bb9c8533)
Solutions
- Use the standard release binary — agent-runtime is part of the default feature set
- Build from source with the feature: `cargo build --release` (default features) or `--features agent-runtime`
- If the binary cannot be swapped, drive the daemon directly: GET/POST `http://<gateway.host>:<gateway.port>[<path_prefix>]/admin/sop/{pending,approve,deny}`
Example fix
# before cargo build --release --no-default-features zeroclaw sop pending # bails: needs agent-runtime # after cargo build --release # default features include agent-runtime zeroclaw sop pending
Defensive patterns
Strategy: fallback
Validate before calling
# smoke-test the binary's capability before scripting SOP approvals out="$(zeroclaw sop pending 2>&1)" || case "$out" in *agent-runtime*) echo "slim build: route SOP admin via HTTP instead"; exit 3 ;; *) echo "$out"; exit 1 ;; esac
Prevention
- Pin the official release binary in deployment tooling so features are known
- After installing any binary, smoke-test `zeroclaw sop pending` once
- Document required cargo features in downstream packaging recipes
When it happens
Trigger: Running `zeroclaw sop pending|approve|deny` on a binary built with `--no-default-features` or otherwise without `agent-runtime` (e.g. slim distro or downstream packaging).
Common situations: Distro/container images that trim cargo features to shrink the binary; custom `cargo build` invocations copying a minimal feature list; a slim CLI paired with a full daemon.
Related errors
- Gateway responded {status}: {err}
- Gateway responded {status}: {detail}
- gateway.path_prefix contains invalid character '{bad}'; only
- candidate SOP did not validate as exactly one loadable SOP
- Gateway feature is not enabled. Rebuild with --features gate
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/05de1d94b1feb37c.
Report an issue: GitHub.