block/buzz · critical

bundled model-capabilities.json must parse

Error message

bundled model-capabilities.json must parse

What it means

buzz-agent embeds scripts/model-capabilities.json at compile time via include_str! and lazily parses it in manifest() behind a OnceLock. A malformed JSON file makes serde_json::from_str return Err and the .expect panics with this message on the first capability lookup (validation failures panic separately). The comment states the intent: this is a build-time data error that must never ship — it indicates the repo's bundled manifest was corrupted, not a user input problem.

Source

Thrown at crates/buzz-agent/src/model_capabilities.rs:238

pub struct CapabilityResult {
    pub thinking_mode: ThinkingMode,
    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

View on GitHub (pinned to dad5a33865)

Solutions

  1. Validate the manifest before building: `jq . scripts/model-capabilities.json >/dev/null` — jq exits non-zero on syntax errors.
  2. Fix the reported JSON error at the exact location (serde's expect prints line/column in the panic).
  3. Add a unit test or CI step that runs the same validate_manifest() used in manifest() so a broken file fails the build, not first use.
  4. After fixing, rebuild — the corrected file is re-embedded by include_str!.

Example fix

# before: broken JSON ships and panics on first use
# thread panicked: bundled model-capabilities.json must parse at line 12 column 3
vi scripts/model-capabilities.json   # remove trailing comma at line 12

# after: gate it in CI
jq . scripts/model-capabilities.json > /dev/null || exit 1
cargo build -p buzz-agent
Defensive patterns

Strategy: validation

Validate before calling

# CI/build gate: fail before shipping a broken manifest
jq . scripts/model-capabilities.json > /dev/null
cargo test -p buzz-agent model_capabilities

Prevention

When it happens

Trigger: Editing scripts/model-capabilities.json and introducing a syntax error (trailing comma, unescaped quote, broken UTF-8), then building and running buzz-agent: the binary compiles fine (include_str! just embeds bytes) but panics on the first call that needs model capabilities, e.g. clamping output tokens or selecting context windows for a model.

Common situations: Hand-editing the manifest to add a new model; a merge conflict in the JSON resolved with conflict markers left inside; CI green on compile but the smoke run panics because nothing in the build validates JSON syntax.

Related errors


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