{"record":{"id":"0a07f26a948abd8b","repo":"Hmbown/CodeWhale","slug":"source-is-not-a-valid-plugin-bundle-error","errorCode":null,"errorMessage":"source is not a valid plugin bundle: {error}","messagePattern":"source is not a valid plugin bundle: (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/plugins/install/stage.rs","lineNumber":100,"sourceCode":"}\n\n/// Copy a local bundle directory into staging. Symlinks anywhere in the\n/// source are rejected; a stale `.installed-from` marker is never copied so\n/// provenance always reflects *this* install.\npub(super) fn stage_local_copy(\n    source: &Path,\n    user_plugins_dir: &Path,\n    max_size: u64,\n) -> Result<StagedPlugin> {\n    // Validate the source first; this also rejects symlinked roots/manifests.\n    let manifest_path =\n        crate::plugins::agent_plugin::resolve_manifest_path(source).ok_or_else(|| {\n            anyhow::anyhow!(\n                \"source is not a valid plugin bundle: no plugin.json, kimi.plugin.json, or plugin.toml\"\n            )\n        })?;\n    PluginManifest::validate_from_path(&manifest_path)\n        .map_err(|error| anyhow::anyhow!(\"source is not a valid plugin bundle: {error}\"))?;\n    let canonical_source = source\n        .canonicalize()\n        .with_context(|| format!(\"failed to resolve {}\", source.display()))?;\n    if let Ok(canonical_plugins) = user_plugins_dir.canonicalize()\n        && (canonical_source == canonical_plugins\n            || canonical_source.starts_with(&canonical_plugins))\n    {\n        bail!(\n            \"cannot install a bundle from inside the user plugins directory {}; \\\n             it is already in place\",\n            canonical_plugins.display()\n        );\n    }\n\n    let staged_path = fresh_staging_dir(user_plugins_dir)?;\n    let result = (|| -> Result<StagedPlugin> {\n        let mut budget = CopyBudget::default();\n        copy_bundle_regular_files(&canonical_source, &staged_path, max_size, &mut budget)?;","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/tui/src/plugins/install/stage.rs#L82-L118","documentation":"Error \"source is not a valid plugin bundle: {error}\" thrown in Hmbown/CodeWhale.","triggerScenarios":"Thrown at crates/tui/src/plugins/install/stage.rs:100 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":[],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}