{"record":{"id":"575bf929403eae53","repo":"Hmbown/CodeWhale","slug":"plugin-path-escapes-plugins-directory","errorCode":null,"errorMessage":"plugin path {} escapes plugins directory {}","messagePattern":"plugin path (.+?) escapes plugins directory (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/plugins/install/place.rs","lineNumber":144,"sourceCode":"    Ok(user_plugins_dir.join(name))\n}\n\n/// The resolved bundle must be a direct child of the resolved plugins root,\n/// matching discovery's fail-closed containment rule.\npub(super) fn ensure_target_within_plugins_dir(\n    target: &Path,\n    user_plugins_dir: &Path,\n) -> Result<()> {\n    let root = fs::canonicalize(user_plugins_dir).with_context(|| {\n        format!(\n            \"failed to resolve plugins directory {}\",\n            user_plugins_dir.display()\n        )\n    })?;\n    let target = fs::canonicalize(target)\n        .with_context(|| format!(\"failed to resolve {}\", target.display()))?;\n    if target.parent() != Some(root.as_path()) {\n        bail!(\n            \"plugin path {} escapes plugins directory {}\",\n            target.display(),\n            root.display()\n        );\n    }\n    Ok(())\n}\n","sourceCodeStart":126,"sourceCodeEnd":152,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/plugins/install/place.rs#L126-L152","documentation":"ensure_target_within_plugins_dir canonicalized both paths and found the plugin's resolved target escapes the resolved plugins root — typically via a symlinked directory. This mirrors discovery's containment rule so a planted link cannot make update/uninstall operate outside the plugins dir.","triggerScenarios":"Thrown at crates/tui/src/plugins/install/place.rs:144 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Remove the symlink and restore a real directory under the plugins root","Retry the operation"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}