Hmbown/CodeWhale · error
Fleet task ' ' metadata.coordination_contracts must contain…
Error message
Fleet task '{}' metadata.coordination_contracts must contain only strings What it means
Each entry of metadata.coordination_contracts must be a JSON string. fleet_coordination_contracts walks the array and fails the task if any element is a non-string (object, number, boolean, null), since contracts are identifier-like strings consumed by the coordination manager.
Solutions
- Replace non-string entries with their string identifiers.
- If contracts were structured objects, extract the identifying field (e.g. `.name`) into a plain string.
- Fix the metadata generator's serializer to emit strings only.
- Trim/validate each entry after conversion — empty strings after trim are also rejected downstream.
Example fix
// before
"coordination_contracts": ["lease:db", {"name": "lock:idx"}]
// after
"coordination_contracts": ["lease:db", "lock:idx"] Defensive patterns
Strategy: type-guard
Validate before calling
if (!contracts.every(c => typeof c === "string" && c.trim() !== "")) throw new Error("coordination_contracts must contain only non-empty strings"); Type guard
function isStringArray(v) { return Array.isArray(v) && v.every(x => typeof x === "string"); } Try / catch
try { build_spec(task) } catch (e) { if (String(e).includes("must contain only strings")) { coerce_contracts_to_strings(task); } else { throw e; } } Prevention
- Serialize contract entries as plain strings, not objects.
- Coerce/extract identifiers from structured contracts at generation time.
- Validate array element types before run creation.
When it happens
Trigger: fleet_task_to_worker_spec_with_profiles -> fleet_coordination_contracts where the array contains a non-string element, e.g. `"coordination_contracts": ["lease:db", 42]` or nested objects describing contracts.
Common situations: Generated metadata serializing contract objects instead of their names; mixed-type arrays from loosely typed config formats; copying contract definitions from another tool that used structured entries.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- fleet task ' ' coordination contracts must be one non-empty…
- fleet task ' ' metadata.coordination_contracts must be an…
- fleet task ' ' metadata.coordination_contracts must contain…
- Fleet task ' ' metadata.coordination_contracts must be an…
- fleet task metadata key is reserved for the durable Runtime…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/340368571e990dbe.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/fleet/worker_runtime.rs:606
let Some(value) = task_spec.metadata.get("coordination_contracts") else {
return Ok(Vec::new());
};
let Some(values) = value.as_array() else {
bail!(
"Fleet task '{}' metadata.coordination_contracts must be an array of strings",
task_spec.id
);
};
if values.len() > 16 {
bail!(
"Fleet task '{}' metadata.coordination_contracts accepts at most 16 entries",
task_spec.id
);
}
let mut contracts = Vec::new();
for value in values {
let Some(value) = value.as_str() else {
bail!(
"Fleet task '{}' metadata.coordination_contracts must contain only strings",
task_spec.id
);
};
let value = value.trim();
if value.is_empty()
|| value.chars().count() > 128
|| value.chars().any(|ch| matches!(ch, '\0' | '\r' | '\n'))
{
bail!(
"Fleet task '{}' coordination contracts must be one non-empty line of at most 128 characters",
task_spec.id
);
}
if !contracts.iter().any(|contract| contract == value) {
contracts.push(value.to_string());
}
}View on GitHub (pinned to 73e0f67d83)