Hmbown/CodeWhale · error
validated Fleet tool authority envelope must serialize
Error message
validated Fleet tool authority envelope must serialize
What it means
Panic while spawning a Fleet worker: the tool authority envelope (a `Serialize` struct) is stringified to pass as `--tool-authority-json` to the `codewhale exec` child process. The message records the upstream assumption that the envelope was validated. `serde_json::to_string` fails when any field cannot appear in JSON: map keys that are not strings, or non-finite floats.
Source
Thrown at crates/tui/src/fleet/executor.rs:271
}
if !exec_config.disallowed_tools.is_empty() {
args.push("--disallowed-tools".to_string());
args.push(exec_config.disallowed_tools.join(","));
}
if exec_config.max_turns > 0 {
args.push("--max-turns".to_string());
args.push(exec_config.max_turns.to_string());
}
if !exec_config.append_system_prompt.trim().is_empty() {
args.push("--append-system-prompt".to_string());
args.push(exec_config.append_system_prompt.clone());
}
if let Some(authority) = authority {
args.push("--tool-authority-json".to_string());
args.push(
serde_json::to_string(authority)
.expect("validated Fleet tool authority envelope must serialize"),
);
}
// The composed task prompt is the final positional argument.
args.push(task_prompt);
FleetWorkerCommand::new(codewhale_binary.to_string(), args)
}
/// Map one `codewhale exec` stream-json line into a fleet ledger event.
///
/// Returns `None` for lines that don't correspond to a worker lifecycle
/// transition (e.g. `session_capture`, `metadata`). The exec event schema is
/// `{"type": "...", ...}` (see `ExecStreamEvent` in `main.rs`).
pub fn map_exec_stream_line(line: &str) -> Option<FleetWorkerEventPayload> {
let value: serde_json::Value = serde_json::from_str(line.trim()).ok()?;
match value.get("type").and_then(serde_json::Value::as_str)? {
"tool_use" => {View on GitHub (pinned to 0c42157ee5)
Solutions
- Identify the recently added field and change it to a string-keyed map (`BTreeMap<String, _>`) or a sanitized number; rebuild.
- Convert the expect into `serde_json::to_string(authority).context(...)?` so a spawn failure carries an actionable error.
- Add a round-trip unit test: `serde_json::to_value(&sample_authority()).unwrap()`.
- Audit sibling CLI argument structs for the same key-type hazard.
Example fix
// before
serde_json::to_string(authority).expect("validated Fleet tool authority envelope must serialize")
// after: fail the worker spawn with an actionable error
let authority_json = serde_json::to_string(authority)
.with_context(|| "serialize tool authority envelope for fleet worker spawn")?; Defensive patterns
Strategy: validation
Validate before calling
// Prove the envelope stringifies before spawning the worker
if serde_json::to_string(authority).is_err() {
return Err(anyhow!("tool authority envelope contains non-JSON-representable fields"));
} Prevention
- Keep envelope fields limited to String/number/bool/Vec/Option and string-keyed maps.
- Round-trip test the envelope (`serde_json::to_value`) whenever fields are added.
When it happens
Trigger: Extending the authority envelope with a `HashMap<u32, _>`-style non-string-keyed map, or an f64 field that received `NaN`/`Infinity` from a config computation; the first fleet run after that change panics while assembling spawn args, before any worker starts.
Common situations: Version skew between the fleet executor struct and newly added authority fields; copying a config struct with non-JSON-friendly key types into the envelope; NaN leaking from default-on-missing arithmetic in config merging.
Related errors
- runtime event JSON is serializable
- bundled model catalog must parse
- ApplyPatchPreflight should serialize
- validated sandbox permission
- sandbox escalation was validated while planning
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/95f5bf4e6e027858.
Report an issue: GitHub.