zeroclaw-labs/zeroclaw · error · anyhow::Error

--domain/--tool are only valid with --level domain-block/too

Error message

--domain/--tool are only valid with --level domain-block/tool-freeze

What it means

`zeroclaw estop` (engage, the default when no subcommand is given) defaults to the kill-all level, which is global and accepts no selectors. `build_engage_level` rejects any `--domain`/`--tool` values when the effective level is kill-all.

Source

Thrown at src/main.rs:6585

            manager.engage(engage_level)?;
            println!("{}", t("cli-estop-engaged", "Estop engaged."));
            print_estop_status(&manager.status());
            Ok(())
        }
    }
}

#[cfg(feature = "agent-runtime")]
fn build_engage_level(
    level: Option<EstopLevelArg>,
    domains: Vec<String>,
    tools: Vec<String>,
) -> Result<security::EstopLevel> {
    let requested = level.unwrap_or(EstopLevelArg::KillAll);
    match requested {
        EstopLevelArg::KillAll => {
            if !domains.is_empty() || !tools.is_empty() {
                bail!("--domain/--tool are only valid with --level domain-block/tool-freeze");
            }
            Ok(security::EstopLevel::KillAll)
        }
        EstopLevelArg::NetworkKill => {
            if !domains.is_empty() || !tools.is_empty() {
                bail!("--domain/--tool are not valid with --level network-kill");
            }
            Ok(security::EstopLevel::NetworkKill)
        }
        EstopLevelArg::DomainBlock => {
            if domains.is_empty() {
                bail!("--level domain-block requires at least one --domain");
            }
            if !tools.is_empty() {
                bail!("--tool is not valid with --level domain-block");
            }
            Ok(security::EstopLevel::DomainBlock(domains))
        }

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Pick the matching level: `zeroclaw estop --level domain-block --domain <d>` or `--level tool-freeze --tool <t>`
  2. Or drop the `--domain`/`--tool` flags to engage a plain global kill-all

Example fix

# before
zeroclaw estop --domain api.example.com
# after
zeroclaw estop --level domain-block --domain api.example.com
Defensive patterns

Strategy: validation

Validate before calling

estop_args_ok() { # $1=level $2=#domains $3=#tools
  case "$1" in
    kill-all|"")          [ "$2" -eq 0 ] && [ "$3" -eq 0 ] ;;
    domain-block)          [ "$2" -gt 0 ] && [ "$3" -eq 0 ] ;;
    tool-freeze)           [ "$3" -gt 0 ] && [ "$2" -eq 0 ] ;;
    *) return 2 ;;
  esac
}
estop_args_ok "$level" "${#domains[@]}" "${#tools[@]}" || { echo "level/selector mismatch"; exit 2; }

Prevention

When it happens

Trigger: `zeroclaw estop --domain api.example.com` or `zeroclaw estop --tool shell --level kill-all` — selector flags supplied without `--level domain-block`/`--level tool-freeze`, or with kill-all chosen explicitly/defaulted.

Common situations: Assuming the CLI infers the level from the provided flags; copy-pasting a domain-block command and deleting the `--level` part; scripts written against an older estop CLI shape.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/370a40ee24de8756. Report an issue: GitHub.