{"record":{"id":"95f5bf4e6e027858","repo":"Hmbown/CodeWhale","slug":"validated-fleet-tool-authority-envelope-must-seria","errorCode":null,"errorMessage":"validated Fleet tool authority envelope must serialize","messagePattern":"validated Fleet tool authority envelope must serialize","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/fleet/executor.rs","lineNumber":271,"sourceCode":"    }\n    if !exec_config.disallowed_tools.is_empty() {\n        args.push(\"--disallowed-tools\".to_string());\n        args.push(exec_config.disallowed_tools.join(\",\"));\n    }\n    if exec_config.max_turns > 0 {\n        args.push(\"--max-turns\".to_string());\n        args.push(exec_config.max_turns.to_string());\n    }\n    if !exec_config.append_system_prompt.trim().is_empty() {\n        args.push(\"--append-system-prompt\".to_string());\n        args.push(exec_config.append_system_prompt.clone());\n    }\n\n    if let Some(authority) = authority {\n        args.push(\"--tool-authority-json\".to_string());\n        args.push(\n            serde_json::to_string(authority)\n                .expect(\"validated Fleet tool authority envelope must serialize\"),\n        );\n    }\n\n    // The composed task prompt is the final positional argument.\n    args.push(task_prompt);\n\n    FleetWorkerCommand::new(codewhale_binary.to_string(), args)\n}\n\n/// Map one `codewhale exec` stream-json line into a fleet ledger event.\n///\n/// Returns `None` for lines that don't correspond to a worker lifecycle\n/// transition (e.g. `session_capture`, `metadata`). The exec event schema is\n/// `{\"type\": \"...\", ...}` (see `ExecStreamEvent` in `main.rs`).\npub fn map_exec_stream_line(line: &str) -> Option<FleetWorkerEventPayload> {\n    let value: serde_json::Value = serde_json::from_str(line.trim()).ok()?;\n    match value.get(\"type\").and_then(serde_json::Value::as_str)? {\n        \"tool_use\" => {","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/fleet/executor.rs#L253-L289","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nserde_json::to_string(authority).expect(\"validated Fleet tool authority envelope must serialize\")\n\n// after: fail the worker spawn with an actionable error\nlet authority_json = serde_json::to_string(authority)\n    .with_context(|| \"serialize tool authority envelope for fleet worker spawn\")?;","handlingStrategy":"validation","validationCode":"// Prove the envelope stringifies before spawning the worker\nif serde_json::to_string(authority).is_err() {\n    return Err(anyhow!(\"tool authority envelope contains non-JSON-representable fields\"));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["rust","serde-json","fleet","process-spawn","panic","expect"],"backgroundTag":"serde-serialization-failed","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}