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

  1. 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)
  2. Run the crate's tests that exercise manifest(): cargo test -p buzz-agent model_capabilities
  3. 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

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


AI-assisted analysis of block/buzz@dad5a33865 (2026-08-20). Data as JSON: /api/errors/fecc195c3e119eb7. Report an issue: GitHub.