Hmbown/CodeWhale · warning
command string
Error message
command string
What it means
In a posture-permission test (crates/tui/src/tools/subagent/tests.rs:8209), `input["command"].as_str().expect("command string")` asserts that the JSON test fixture has a `"command"` key holding a string. It is a test-local sanity check on fixture data. A panic means one of the iterated fixture objects lacks `"command"` or stores it as a non-string.
Solutions
- Check every fixture in the iterated array has a string `"command"` field.
- If a fixture legitimately has no command, handle it inside the loop before the `expect`.
- Extract command extraction into a helper that returns `Option<&str>` and `assert!` with a descriptive message naming the failing fixture.
- Add a compile-time or setup assertion that all fixtures share the same shape.
Example fix
// before
let command = input["command"].as_str().expect("command string").to_string();
// after
let command = input["command"].as_str()
.unwrap_or_else(|| panic!("fixture missing string command: {input}"))
.to_string(); Defensive patterns
Strategy: validation
Validate before calling
// Validate fixture shape before the loop body
for input in fixtures {
assert!(input.get("command").and_then(|c| c.as_str()).is_some(),
"fixture missing string command: {input}");
} Type guard
fn fixture_command(input: &serde_json::Value) -> Option<&str> {
input.get("command").and_then(|v| v.as_str())
} Try / catch
// Fail loudly with the offending fixture
let command = input.get("command").and_then(|v| v.as_str())
.unwrap_or_else(|| panic!("fixture missing string command: {input}")); Prevention
- Keep all fixtures in a parameterized loop shape-identical.
- Assert fixture schema once in a shared helper instead of scattering expects.
- Include the fixture JSON in panic messages for quick diagnosis.
- Review every new entry added to a fixture array for required keys.
When it happens
Trigger: Editing or adding a fixture in the loop `[json!({"command": "pwd"}), json!({"command": git_log.as_str()}), ...]` so a variant omits `"command"` or uses a non-string value.
Common situations: Renaming the fixture key, making `command` conditional, or building the JSON dynamically where the key is absent.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15).
Data as JSON: /api/errors/8ec6d6c1a350ff04.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tools/subagent/tests.rs:8209
runtime.context = ToolContext::new(workspace.clone());
runtime.worker_profile = WorkerRuntimeProfile::for_role(role.clone());
seed_read_only_role_deny_list(&mut runtime);
let registry = SubAgentToolRegistry::new(
runtime,
role.clone(),
None,
crate::tools::todo::new_shared_todo_list(),
crate::tools::plan::new_shared_plan_state(),
);
for input in [
json!({"command": "pwd"}),
json!({"command": git_log.as_str()}),
json!({"command": git_log.as_str(), "timeout": 5}),
] {
let command = input["command"]
.as_str()
.expect("command string")
.to_string();
assert!(
registry.posture_permits_tool("bash", Some(&input)),
"{role:?} posture must admit {command}"
);
assert!(
registry.envelope_refusal("bash", &input).is_none(),
"{role:?} envelope must admit {command}"
);
let output = registry
.execute("agent_read_only_e2e", "bash", input)
.await
.unwrap_or_else(|error| {
panic!("{role:?} concrete executor must run {command}: {error}")
});
assert!(!output.trim().is_empty(), "{role:?} {command}");
}
}View on GitHub (pinned to 433685b202)