block/buzz · warning · ValidationDiagnostic::Warning

plugin.json unknown key "{key}"

Error message

plugin.json unknown key "{key}"

What it means

Advisory lint during persona pack validation: plugin.json carries a top-level key not listed in KNOWN_MANIFEST_KEYS ($schema, id, name, version, description, author, license, homepage, repository, keywords, engines, personas, defaults, pack_instructions, hooks_config, mcp_config). It is emitted as a warning on the ValidationReport and does not abort loading the pack.

Source

Thrown at crates/buzz-persona/src/validate.rs:321

    let manifest_path = pack_dir.join(".plugin").join("plugin.json");
    let content = match std::fs::read_to_string(&manifest_path) {
        Ok(c) => c,
        Err(_) => return, // load_pack already caught this
    };
    let json: serde_json::Value = match serde_json::from_str(&content) {
        Ok(v) => v,
        Err(_) => return, // load_pack already caught this
    };
    let obj = match json.as_object() {
        Some(o) => o,
        None => return,
    };

    // Top-level unknown keys.
    let known_manifest: HashSet<&str> = KNOWN_MANIFEST_KEYS.iter().copied().collect();
    for key in obj.keys() {
        if !known_manifest.contains(key.as_str()) {
            report.warn(format!("plugin.json unknown key \"{key}\""));
        }
    }

    // Unknown keys in `defaults`.
    if let Some(defaults) = obj.get("defaults").and_then(|v| v.as_object()) {
        let known_behavioral: HashSet<&str> = KNOWN_BEHAVIORAL_KEYS.iter().copied().collect();
        for key in defaults.keys() {
            if !known_behavioral.contains(key.as_str()) {
                report.warn(format!("plugin.json defaults: unknown key \"{key}\""));
            }
        }

        // Unknown keys in `defaults.triggers` (or legacy `defaults.respond_to`).
        let triggers_obj = defaults
            .get("triggers")
            .or_else(|| defaults.get("respond_to"))
            .and_then(|v| v.as_object());
        if let Some(rt) = triggers_obj {

View on GitHub (pinned to 934f3325c3)

Solutions

  1. Compare the offending key against KNOWN_MANIFEST_KEYS in crates/buzz-persona/src/validate.rs:99 and remove or rename it
  2. Upgrade buzz-persona if the key is legitimately part of a newer manifest spec
  3. Validate packs in CI with the same validator so unknown keys surface before publishing

Example fix

// before (plugin.json)
{ "name": "helper", "display_name": "Helper" }

// after
{ "name": "helper", "description": "Helper persona" }
Defensive patterns

Strategy: validation

Validate before calling

const KNOWN_MANIFEST_KEYS = new Set([
  "$schema", "id", "name", "version", "description", "author", "license",
  "homepage", "repository", "keywords", "engines", "personas", "defaults",
  "pack_instructions", "hooks_config", "mcp_config",
]); // sync with crates/buzz-persona/src/validate.rs
for (const key of Object.keys(manifest)) {
  if (!KNOWN_MANIFEST_KEYS.has(key)) throw new Error(`plugin.json unknown top-level key: ${key}`);
}

Type guard

const isKnownManifestKey = (k: string): k is ManifestKey => KNOWN_MANIFEST_KEYS.has(k as ManifestKey);

Prevention

When it happens

Trigger: A hand-edited plugin.json with a typo'd or speculative top-level key; manifests written by external tooling that injects its own metadata fields; keys from a newer persona-pack spec than this buzz-persona build recognizes.

Common situations: Authoring packs against newer or older docs; copy-pasting manifests between plugin ecosystems (e.g. Claude-style plugin.json) into a Buzz persona pack; IDE auto-completing plausible-but-unsupported fields.

Related errors


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