zeroclaw-labs/zeroclaw · error · anyhow::Error
--level tool-freeze requires at least one --tool
Error message
--level tool-freeze requires at least one --tool
What it means
Argument-consistency guard in ESTOP level parsing: --level tool-freeze was given without any --tool flags. Tool-freeze disables specific tools, so an empty tool list would freeze nothing and is refused. Supply one or more --tool values with this level.
Solutions
- Add one or more `--tool <name>` values
- Check flag spelling and shell expansion: the flag is `--tool` (repeatable) and variables must expand non-empty
- Use no `--level` (kill-all default) if a global stop was intended
Example fix
# before zeroclaw estop --level tool-freeze # after zeroclaw estop --level tool-freeze --tool shell
Defensive patterns
Strategy: validation
Validate before calling
if [ "$level" = "tool-freeze" ] && [ "${#tools[@]}" -eq 0 ]; then
echo "--level tool-freeze requires at least one --tool"; exit 2
fi Prevention
- Validate the tool list against known tool names before engaging a freeze
- Use `set -u` and explicit array initialization so empty lists are impossible
When it happens
Trigger: `zeroclaw estop --level tool-freeze` with no `--tool` flags supplied.
Common situations: Typo in the flag name (`--tools`); empty/unexpanded tool list variable in automation; forgetting the selector when adapting a domain-block example.
Understand the failure class
Background: "--flag is required" and "must specify" CLI errors: how missing-required-flag validation works and how to fix it — this error's family across 20 libraries.
Related errors
- --domain is not valid with --level tool-freeze
- --domain/--tool are not valid with --level network-kill
- --domain/--tool are only valid with --level…
- --level domain-block requires at least one --domain
- --tool is not valid with --level domain-block
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/efcdd933bd5129f3.
Report an issue: GitHub.
Appendix: source
Thrown at src/main.rs:6606
}
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))
}
EstopLevelArg::ToolFreeze => {
if tools.is_empty() {
bail!("--level tool-freeze requires at least one --tool");
}
if !domains.is_empty() {
bail!("--domain is not valid with --level tool-freeze");
}
Ok(security::EstopLevel::ToolFreeze(tools))
}
}
}
#[cfg(feature = "agent-runtime")]
fn build_resume_selector(
network: bool,
domains: Vec<String>,
tools: Vec<String>,
) -> Result<security::ResumeSelector> {
let selected =
usize::from(network) + usize::from(!domains.is_empty()) + usize::from(!tools.is_empty());
if selected > 1 {View on GitHub (pinned to 88bb9c8533)