xai-org/grok-build · error

Failed to load manifest: {e}

Error message

Failed to load manifest: {e}

What it means

`grok plugin validate` failed to read or parse the plugin.json manifest in the target directory. When load_manifest returns an Err (not merely NotFound), the command bails with 'Failed to load manifest: {e}', embedding the underlying parse/IO error. This guards against silently validating a plugin whose metadata is corrupt.

Source

Thrown at crates/codegen/xai-grok-pager/src/plugin_cmd.rs:709

            println!("  name: {}", manifest.name);
            if let Some(ref v) = manifest.version {
                println!("  version: {v}");
            }
            if let Some(ref d) = manifest.description {
                println!("  description: {d}");
            }
            print_component_summary(&manifest, &root);
            Ok(())
        }
        Ok(ManifestLoadResult::NotFound) => {
            println!(
                "No plugin.json found. Grok discovers skills, agents, and hooks \
                 automatically from standard directories. A manifest is only needed \
                 for custom paths or metadata."
            );
            Ok(())
        }
        Err(e) => bail!("Failed to load manifest: {e}"),
    }
}

fn cmd_tag(path: &str, push: bool, force: bool, dry_run: bool) -> Result<()> {
    let root = PathBuf::from(path);
    if !root.is_dir() {
        bail!("Not a directory: {path}");
    }
    let version = match load_manifest(&root) {
        Ok(ManifestLoadResult::Found(m)) => m.version.ok_or_else(|| {
            anyhow::anyhow!(
                "No `version` field in plugin.json. Set a version to use `grok plugin tag`."
            )
        })?,
        Ok(ManifestLoadResult::NotFound) => bail!("No plugin.json found in {path}."),
        Err(e) => bail!("Failed to load manifest: {e}"),
    };

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Open plugin.json and fix the JSON syntax error shown in the embedded {e} message
  2. Validate the file with `jq . plugin.json` or a JSON linter
  3. Check file permissions so the current user can read plugin.json
  4. If no manifest is needed, delete plugin.json — validate treats NotFound as OK

Example fix

// before
{
  "name": "my-plugin",
  "version": "1.0.0",
}
// after (trailing comma removed)
{
  "name": "my-plugin",
  "version": "1.0.0"
}
Defensive patterns

Strategy: validation

Validate before calling

use std::path::Path;
fn manifest_is_valid(dir: &Path) -> Result<(), String> {
    let f = dir.join("plugin.json");
    let s = std::fs::read_to_string(&f)
        .map_err(|e| format!("cannot read {}: {e}", f.display()))?;
    serde_json::from_str::<serde_json::Value>(&s)
        .map(|_| ())
        .map_err(|e| format!("invalid plugin.json: {e}"))
}

Type guard

fn has_readable_manifest(dir: &std::path::Path) -> bool {
    dir.join("plugin.json").is_file()
}

Try / catch

match cmd_validate(dir) {
    Err(e) if e.to_string().contains("Failed to load manifest") => {
        eprintln!("Fix plugin.json: {e}");
    }
    Ok(_) => {}
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Running `grok plugin validate <path>` where a plugin.json exists but is unreadable (permissions) or invalid JSON/schema, causing load_manifest to return Err.

Common situations: Hand-edited plugin.json with a trailing comma or JSON5 syntax; file locked by an editor; wrong file permissions; plugin.json written by a tool emitting non-JSON output.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/87627d3130dd3b55. Report an issue: GitHub.