{"record":{"id":"5f8affe74c15aa53","repo":"Hmbown/CodeWhale","slug":"fleet-task-metadata-coordination-contracts-ac","errorCode":null,"errorMessage":"fleet task '{}' metadata.coordination_contracts accepts at most 16 entries","messagePattern":"fleet task '(.+?)' metadata\\.coordination_contracts accepts at most 16 entries","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/fleet/worker_runtime.rs","lineNumber":389,"sourceCode":"    Ok(if segments.is_empty() {\n        \".\".to_string()\n    } else {\n        segments.join(\"/\")\n    })\n}\n\nfn fleet_coordination_contracts(task_spec: &FleetTaskSpec) -> Result<Vec<String>> {\n    let Some(value) = task_spec.metadata.get(\"coordination_contracts\") else {\n        return Ok(Vec::new());\n    };\n    let Some(values) = value.as_array() else {\n        bail!(\n            \"fleet task '{}' metadata.coordination_contracts must be an array of strings\",\n            task_spec.id\n        );\n    };\n    if values.len() > 16 {\n        bail!(\n            \"fleet task '{}' metadata.coordination_contracts accepts at most 16 entries\",\n            task_spec.id\n        );\n    }\n    let mut contracts = Vec::new();\n    for value in values {\n        let Some(value) = value.as_str() else {\n            bail!(\n                \"fleet task '{}' metadata.coordination_contracts must contain only strings\",\n                task_spec.id\n            );\n        };\n        let value = value.trim();\n        if value.is_empty()\n            || value.chars().count() > 128\n            || value.chars().any(|ch| matches!(ch, '\\0' | '\\r' | '\\n'))\n        {\n            bail!(","sourceCodeStart":371,"sourceCodeEnd":407,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/fleet/worker_runtime.rs#L371-L407","documentation":"The `metadata.coordination_contracts` array exceeds the hard cap of 16 entries. The limit keeps the coordination surface of a fleet task small and auditable; entries beyond 16 are not silently dropped — the whole spec is rejected. Duplicate strings are deduplicated later, but the length check runs on the raw array before dedup.","triggerScenarios":"A spec listing 17+ contract strings, including duplicates (dedup happens after the count check, so 20 entries with 3 duplicates still fails).","commonSituations":"Generators enumerating every queue/topic as a contract; accumulated contracts from merging several task templates.","solutions":["Trim the list to at most 16 entries, removing duplicates first so the cap counts unique contracts.","Consolidate fine-grained contracts into broader ones (e.g. one \"ledger\" instead of per-table entries).","If contracts are generated, cap the generator at 16 and log when it truncates."],"exampleFix":"# before\n[metadata]\ncoordination_contracts = [\"a\", \"b\", \"c\", ... 20 entries ...]\n\n# after\n[metadata]\ncoordination_contracts = [\"a\", \"b\", \"c\"]  # <= 16 unique entries","handlingStrategy":"validation","validationCode":"const MAX_CONTRACTS: usize = 16;\n\nfn contracts_within_limit(values: &[serde_json::Value]) -> bool {\n    values.len() <= MAX_CONTRACTS\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Deduplicate contracts before counting — the runtime's cap applies to the raw array.","Model contracts as a small fixed enum/slug list, not an open-ended generated set.","Fail loudly in generators when truncation would be needed rather than silently exceeding 16."],"tags":["fleet","metadata","coordination","limits","rust"],"backgroundTag":"config-limit-exceeded","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}