{"record":{"id":"9e3afd98f46edd75","repo":"xai-org/grok-build","slug":"no-plugin-json-found-in-path","errorCode":null,"errorMessage":"No plugin.json found in {path}.","messagePattern":"No plugin\\.json found in (.+?)\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-pager/src/plugin_cmd.rs","lineNumber":724,"sourceCode":"            );\n            Ok(())\n        }\n        Err(e) => bail!(\"Failed to load manifest: {e}\"),\n    }\n}\n\nfn cmd_tag(path: &str, push: bool, force: bool, dry_run: bool) -> Result<()> {\n    let root = PathBuf::from(path);\n    if !root.is_dir() {\n        bail!(\"Not a directory: {path}\");\n    }\n    let version = match load_manifest(&root) {\n        Ok(ManifestLoadResult::Found(m)) => m.version.ok_or_else(|| {\n            anyhow::anyhow!(\n                \"No `version` field in plugin.json. Set a version to use `grok plugin tag`.\"\n            )\n        })?,\n        Ok(ManifestLoadResult::NotFound) => bail!(\"No plugin.json found in {path}.\"),\n        Err(e) => bail!(\"Failed to load manifest: {e}\"),\n    };\n\n    let tag = format!(\n        \"v{}\",\n        version\n            .strip_prefix('v')\n            .or_else(|| version.strip_prefix('V'))\n            .unwrap_or(&version)\n    );\n\n    if !force {\n        let out = std::process::Command::new(\"git\")\n            .args([\"status\", \"--porcelain\"])\n            .current_dir(&root)\n            .output()?;\n        if !out.stdout.is_empty() {\n            bail!(\"Working tree is dirty. Commit changes first, or use --force.\");","sourceCodeStart":706,"sourceCodeEnd":742,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-pager/src/plugin_cmd.rs#L706-L742","documentation":"`grok plugin tag` needs a version from plugin.json to build the v<version> git tag. If load_manifest reports the directory has no plugin.json (ManifestLoadResult::NotFound), the command bails with 'No plugin.json found in {path}.'","triggerScenarios":"Running `grok plugin tag <dir>` on a directory that does not contain a plugin.json file.","commonSituations":"Tagging a fresh plugin before creating its manifest; pointing at the repo root instead of the plugin subdirectory; plugin.json accidentally deleted or renamed.","solutions":["Create a plugin.json in the target directory with at least name and version fields","Point the command at the directory that actually contains plugin.json","If only tagging was needed, create the git tag manually: `git tag v1.0.0`"],"exampleFix":"// before: directory has no manifest, tag fails\n// after: add plugin.json\n{\n  \"name\": \"my-plugin\",\n  \"version\": \"1.0.0\"\n}","handlingStrategy":"validation","validationCode":"use std::path::Path;\nfn ensure_manifest(dir: &Path) -> Result<(), String> {\n    if !dir.join(\"plugin.json\").is_file() {\n        return Err(format!(\n            \"No plugin.json found in {}; create one with name+version\",\n            dir.display()\n        ));\n    }\n    Ok(())\n}","typeGuard":"fn has_manifest(dir: &std::path::Path) -> bool {\n    dir.join(\"plugin.json\").is_file()\n}","tryCatchPattern":"match cmd_tag(dir, false, false, false) {\n    Err(e) if e.to_string().contains(\"No plugin.json found\") => {\n        eprintln!(\"Create plugin.json with a version field first\");\n    }\n    Ok(_) => {}\n    Err(e) => return Err(e),\n}","preventionTips":["Scaffold every plugin with a plugin.json (name + version) from day one","Scaffold tools should fail if the manifest is missing","Keep manifests versioned in git so they can't be silently deleted"],"tags":["manifest","plugin","cli","missing-file"],"backgroundTag":"manifest-not-found","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}