{"record":{"id":"2f2a6b5170a7580a","repo":"Hmbown/CodeWhale","slug":"refusing-to-import-unsafe-external-skill-package","errorCode":null,"errorMessage":"refusing to import unsafe external skill package","messagePattern":"refusing to import unsafe external skill package","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/skills/mutation.rs","lineNumber":654,"sourceCode":"            after_digest: None,\n            outcome: SkillMutationOutcome::NetworkDenied(host),\n        }),\n    }\n}\n\nfn import_external(\n    source_id: AuditedSkillId,\n    expected_digest: String,\n    target: SkillTargetScope,\n    conflict_policy: ConflictPolicy,\n    ctx: &MutationContext<'_>,\n) -> Result<SkillMutationReceipt> {\n    let (source_skill, source_path) = find_audited_skill(ctx, &source_id)?;\n    if source_skill.source_kind != SkillSourceKind::CompatibleExternal {\n        bail!(\"import source must be a compatible external skill\");\n    }\n    if source_skill.path_unsafe {\n        bail!(\"refusing to import unsafe external skill package\");\n    }\n\n    let owned_snap = scan_with_configured(\n        ctx.workspace,\n        ctx.home,\n        ctx.configured_skills_dir,\n        SkillAuditMode::OwnedOnly,\n        None,\n    );\n    let owned_has_name = owned_snap\n        .skills\n        .iter()\n        .any(|s| s.id.canonical_name == source_id.canonical_name);\n\n    if !owned_has_name && !source_skill.import_candidate {\n        bail!(\"skill is not an import candidate\");\n    }\n","sourceCodeStart":636,"sourceCodeEnd":672,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/skills/mutation.rs#L636-L672","documentation":"Raised in import_external when the audited source package is flagged path_unsafe. The audit marks a package path-unsafe when it contains symlinks or otherwise escapes its expected root; import refuses to copy such packages as a security fail-closed measure before any filesystem write.","triggerScenarios":"Thrown at crates/tui/src/skills/mutation.rs:654 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Inspect the external skill directory for symlinks or unexpected path structures and replace them with regular files","Re-install or re-download the external skill package from its origin","Re-scan so the audit clears the path_unsafe flag, then retry the import"],"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"}