block/buzz · critical
bundled model-capabilities.json failed validation: {e}
Error message
bundled model-capabilities.json failed validation: {e} What it means
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.
Source
Thrown at crates/buzz-agent/src/model_capabilities.rs:240
pub supported_efforts: &'static [ThinkingEffort],
pub default_effort: Option<ThinkingEffort>,
pub databricks_v2_wire_route: DatabricksV2Route,
pub normalization_policy: NormalizationPolicy,
pub registry_label: Option<&'static str>,
}
const MANIFEST_JSON: &str = include_str!("../../../scripts/model-capabilities.json");
static MANIFEST: OnceLock<Manifest> = OnceLock::new();
/// Parse (once) and return the embedded manifest. Panics on a malformed or
/// invalid bundled manifest — a build-time data error that must never ship.
fn manifest() -> &'static Manifest {
MANIFEST.get_or_init(|| {
let parsed: Manifest = serde_json::from_str(MANIFEST_JSON)
.expect("bundled model-capabilities.json must parse");
if let Err(e) = validate_manifest(&parsed) {
panic!("bundled model-capabilities.json failed validation: {e}");
}
parsed
})
}
/// Canonicalize a provider name: trim, lowercase, apply the alias map.
fn canonical_provider(provider: &str) -> String {
let canon = provider.trim().to_ascii_lowercase();
match canon.as_str() {
"openai-compat" => "openai".to_string(),
"databricks-v2" => "databricks_v2".to_string(),
_ => canon,
}
}
/// Strip an endpoint-naming prefix by locating the earliest family token that
/// begins on a non-alphanumeric boundary (or at the start), returning the slice
/// from that token onward. Returns the input unchanged when no token qualifies.View on GitHub (pinned to dad5a33865)
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)
Example fix
// scripts/model-capabilities.json
// before
{"models": [{"id": "gpt-4o", "provider": "openai"}, {"id": "gpt-4o", "provider": "openai"}]}
// after (unique ids, all required fields present)
{"models": [{"id": "gpt-4o", "provider": "openai"}, {"id": "gpt-4o-mini", "provider": "openai"}]} Defensive patterns
Strategy: validation
Validate before calling
// CI / pre-merge: fail before the bad data ships
// (add as a unit test in crates/buzz-agent/src/model_capabilities.rs)
#[test]
fn bundled_manifest_is_valid() {
let parsed: Manifest = serde_json::from_str(MANIFEST_JSON)
.expect("bundled model-capabilities.json must parse");
validate_manifest(&parsed)
.expect("bundled model-capabilities.json failed validation");
} Try / catch
// If you embed buzz-agent: surface the one-time panic as a build error, not a runtime crash
let manifest = std::panic::catch_unwind(model_capabilities::manifest)
.unwrap_or_else(|panic| panic!("agent image was built with an invalid model manifest: {panic:?}")); Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- bundled model-capabilities.json must parse
- plugin.json unknown key "{key}"
- failed to install rustls crypto provider
- nip98 mode always resolves principal
- metrics exporter must install exactly once: {error}
AI-assisted analysis of block/buzz@dad5a33865 (2026-08-20).
Data as JSON: /api/errors/fecc195c3e119eb7.
Report an issue: GitHub.