Hmbown/CodeWhale · error
Fleet task ' ' metadata.coordination_contracts must be an…
Error message
Fleet task '{}' metadata.coordination_contracts must be an array of strings What it means
fleet_coordination_contracts reads task_spec.metadata["coordination_contracts"]; when the key exists but its value is not a JSON array, the task cannot form a coordination claim and the spec build fails. Contracts must be an array of strings (bounded at 16 entries).
Solutions
- Wrap the value in an array: `"coordination_contracts": ["contract-a"]`.
- Remove the metadata key entirely if no contracts are needed (missing key is valid and returns an empty vec).
- Fix the metadata producer to emit a JSON array of strings.
- Validate run JSON before submission so malformed metadata is caught early.
Example fix
// before
"metadata": { "coordination_contracts": "lease:db-migration" }
// after
"metadata": { "coordination_contracts": ["lease:db-migration"] } Defensive patterns
Strategy: type-guard
Validate before calling
const contracts = run.metadata?.coordination_contracts;
if (contracts !== undefined && !Array.isArray(contracts)) throw new Error("coordination_contracts must be an array"); 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 be an array of strings")) { fix_metadata_shape(task); } else { throw e; } } Prevention
- Emit coordination_contracts only as arrays of strings.
- Omit the key entirely when there are no contracts.
- Schema-validate run JSON before creating the run.
When it happens
Trigger: fleet_task_to_worker_spec_with_profiles -> fleet_coordination_contracts where metadata contains `coordination_contracts` as a string (e.g. `"contract-a"`), object, or number instead of an array.
Common situations: Hand-editing fleet run JSON and writing the contract as a single string instead of a one-element array; YAML/JSON type confusion where a quoted string was intended as a list; programmatic metadata writers storing the field under the wrong shape.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Facts must be scalar metadata, not content objects.
- 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 key is reserved for the durable Runtime…
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/21dc63322d0bdf25.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/fleet/worker_runtime.rs:592
path.display()
);
}
value => segments.push(value),
}
}
Ok(if segments.is_empty() {
".".to_string()
} else {
segments.join("/")
})
}
fn fleet_coordination_contracts(task_spec: &FleetTaskSpec) -> Result<Vec<String>> {
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
);
};View on GitHub (pinned to 73e0f67d83)