{"record":{"id":"41702edce566e18d","repo":"Hmbown/CodeWhale","slug":"refusing-to-remove-skill-outside-codewhale-owned-r","errorCode":null,"errorMessage":"refusing to remove skill outside CodeWhale-owned roots","messagePattern":"refusing to remove skill outside CodeWhale-owned roots","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/skills/mutation.rs","lineNumber":942,"sourceCode":"            action: SkillActionKind::Update,\n            name: skill_id.canonical_name,\n            scope,\n            safe_target_path: safe_display_path(&path, Some(ctx.workspace), ctx.home),\n            before_digest: before,\n            after_digest: None,\n            outcome: SkillMutationOutcome::NetworkDenied(host),\n        }),\n    }\n}\n\nfn remove_skill(\n    skill_id: AuditedSkillId,\n    expected_digest: Option<String>,\n    ctx: &MutationContext<'_>,\n) -> Result<SkillMutationReceipt> {\n    let (skill, path) = find_audited_skill(ctx, &skill_id)?;\n    if !skill.root.is_writable_owned() {\n        bail!(\"refusing to remove skill outside CodeWhale-owned roots\");\n    }\n    if skill.source_kind != SkillSourceKind::CodeWhaleManaged {\n        bail!(\"only CodeWhale managed skills can be removed\");\n    }\n    let skills_dir = validate_owned_skill_path(ctx, &skill, &path)?;\n    let before = verify_expected_digest(&path, expected_digest.as_deref())?;\n    let scope = match skill.root.kind {\n        SkillRootKind::CodeWhaleProject => SkillScope::Project,\n        SkillRootKind::CodeWhaleGlobal => SkillScope::Global,\n        _ => SkillScope::Logical,\n    };\n    let package_name = on_disk_package_name(&skill_id)?;\n    validate_owned_skill_path(ctx, &skill, &path)?;\n    install::uninstall(package_name, &skills_dir)?;\n    Ok(SkillMutationReceipt {\n        action: SkillActionKind::Remove,\n        name: skill_id.canonical_name,\n        scope,","sourceCodeStart":924,"sourceCodeEnd":960,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/skills/mutation.rs#L924-L960","documentation":"Raised in remove_skill when the audited skill's root is not a writable CodeWhale-owned root. Removal deletes directories, so it is restricted to skill roots the tool owns; skills merely discovered from external locations cannot be deleted through this path.","triggerScenarios":"Thrown at crates/tui/src/skills/mutation.rs:942 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Remove the skill using its own installer or by deleting the directory manually","Only call remove on skills located in CodeWhale-owned scopes","Confirm the skill id targets the owned copy if both owned and external copies exist"],"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"}