{"record":{"id":"fecc195c3e119eb7","repo":"block/buzz","slug":"bundled-model-capabilities-json-failed-validation","errorCode":null,"errorMessage":"bundled model-capabilities.json failed validation: {e}","messagePattern":"bundled model-capabilities\\.json failed validation: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/buzz-agent/src/model_capabilities.rs","lineNumber":240,"sourceCode":"    pub supported_efforts: &'static [ThinkingEffort],\n    pub default_effort: Option<ThinkingEffort>,\n    pub databricks_v2_wire_route: DatabricksV2Route,\n    pub normalization_policy: NormalizationPolicy,\n    pub registry_label: Option<&'static str>,\n}\n\nconst MANIFEST_JSON: &str = include_str!(\"../../../scripts/model-capabilities.json\");\n\nstatic MANIFEST: OnceLock<Manifest> = OnceLock::new();\n\n/// Parse (once) and return the embedded manifest. Panics on a malformed or\n/// invalid bundled manifest — a build-time data error that must never ship.\nfn manifest() -> &'static Manifest {\n    MANIFEST.get_or_init(|| {\n        let parsed: Manifest = serde_json::from_str(MANIFEST_JSON)\n            .expect(\"bundled model-capabilities.json must parse\");\n        if let Err(e) = validate_manifest(&parsed) {\n            panic!(\"bundled model-capabilities.json failed validation: {e}\");\n        }\n        parsed\n    })\n}\n\n/// Canonicalize a provider name: trim, lowercase, apply the alias map.\nfn canonical_provider(provider: &str) -> String {\n    let canon = provider.trim().to_ascii_lowercase();\n    match canon.as_str() {\n        \"openai-compat\" => \"openai\".to_string(),\n        \"databricks-v2\" => \"databricks_v2\".to_string(),\n        _ => canon,\n    }\n}\n\n/// Strip an endpoint-naming prefix by locating the earliest family token that\n/// begins on a non-alphanumeric boundary (or at the start), returning the slice\n/// from that token onward. Returns the input unchanged when no token qualifies.","sourceCodeStart":222,"sourceCodeEnd":258,"githubUrl":"https://github.com/block/buzz/blob/dad5a33865fc81a2e55b3b60746632f615ec1e3a/crates/buzz-agent/src/model_capabilities.rs#L222-L258","documentation":"buzz-agent embeds scripts/model-capabilities.json at compile time (include_str!) and lazily parses and validates it on the first manifest() call. This panic means the bundled JSON parsed as JSON but failed validate_manifest(): the shipped data is internally inconsistent (e.g. duplicate provider/model ids, unknown provider, missing required fields), which the code deliberately treats as a build-time data error that must never ship.","triggerScenarios":"Editing scripts/model-capabilities.json (adding a provider, alias, or model entry) so that validate_manifest()'s invariants break, then building and running any buzz-agent or sprig code path that first calls manifest(); the panic fires once at first model-capability lookup.","commonSituations":"A contributor updates model-capabilities.json for a new model but duplicates an id or omits a required field; validation only runs at runtime on first use, so the bad data merges and every downstream agent run panics at startup or on first capability check.","solutions":["Fix scripts/model-capabilities.json to satisfy validate_manifest (check for duplicate provider/model ids and missing required fields against the Manifest struct in crates/buzz-agent/src/model_capabilities.rs)","Run the crate's tests that exercise manifest(): cargo test -p buzz-agent model_capabilities","Add a CI check that validates the JSON before merge (a unit test calling validate_manifest on the include_str!'d data)"],"exampleFix":"// scripts/model-capabilities.json\n// before\n{\"models\": [{\"id\": \"gpt-4o\", \"provider\": \"openai\"}, {\"id\": \"gpt-4o\", \"provider\": \"openai\"}]}\n// after (unique ids, all required fields present)\n{\"models\": [{\"id\": \"gpt-4o\", \"provider\": \"openai\"}, {\"id\": \"gpt-4o-mini\", \"provider\": \"openai\"}]}","handlingStrategy":"validation","validationCode":"// CI / pre-merge: fail before the bad data ships\n// (add as a unit test in crates/buzz-agent/src/model_capabilities.rs)\n#[test]\nfn bundled_manifest_is_valid() {\n    let parsed: Manifest = serde_json::from_str(MANIFEST_JSON)\n        .expect(\"bundled model-capabilities.json must parse\");\n    validate_manifest(&parsed)\n        .expect(\"bundled model-capabilities.json failed validation\");\n}","typeGuard":null,"tryCatchPattern":"// If you embed buzz-agent: surface the one-time panic as a build error, not a runtime crash\nlet manifest = std::panic::catch_unwind(model_capabilities::manifest)\n    .unwrap_or_else(|panic| panic!(\"agent image was built with an invalid model manifest: {panic:?}\"));","preventionTips":["Never edit scripts/model-capabilities.json without running cargo test -p buzz-agent model_capabilities in the same change","Keep a CI job that validates the bundled manifest on every PR touching scripts/*.json"],"tags":["rust","json","manifest","panic","build-data","buzz-agent"],"backgroundTag":"bundled-manifest-validation-failed","analyzedSha":"dad5a33865fc81a2e55b3b60746632f615ec1e3a","analyzedAt":"2026-08-20T04:38:24.874Z","contentChangedAt":"2026-08-20T04:38:24.874Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}