{"record":{"id":"c3854ca3baab7944","repo":"Hmbown/CodeWhale","slug":"dsh-plugin-remove-bundle-package-name-failed","errorCode":null,"errorMessage":"dsh plugin remove {BUNDLE_PACKAGE_NAME} failed: {}","messagePattern":"dsh plugin remove (.+?) failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/integrations/dsh/bundle.rs","lineNumber":370,"sourceCode":"    Ok((app_source, outcomes))\n}\n\npub(crate) fn remove_from_profile(\n    runner: &dyn DshRunner,\n    detection: &DshDetection,\n) -> Result<PluginCommandOutcome> {\n    let binary = detection\n        .binary\n        .as_ref()\n        .ok_or_else(|| anyhow::anyhow!(\"dsh binary is unknown\"))?;\n    let outcome = run_dsh_plugin(\n        runner,\n        binary,\n        BUNDLE_PROFILE,\n        &[\"remove\", BUNDLE_PACKAGE_NAME],\n    )?;\n    if !outcome.success {\n        anyhow::bail!(\n            \"dsh plugin remove {BUNDLE_PACKAGE_NAME} failed: {}\",\n            outcome.output_excerpt\n        );\n    }\n    Ok(outcome)\n}\n\n/// Read the dedicated profile's `dsh.profile.bundles` (DSH-owned manifest,\n/// read-only) so status can prove the bundle is actually composed.\npub(crate) fn profile_bundles(profile_dir: &Path) -> Option<Vec<String>> {\n    let text = std::fs::read_to_string(profile_dir.join(\"package.json\")).ok()?;\n    let json: serde_json::Value = serde_json::from_str(&text).ok()?;\n    Some(\n        json.get(\"dsh\")?\n            .get(\"profile\")?\n            .get(\"bundles\")?\n            .as_array()?\n            .iter()","sourceCodeStart":352,"sourceCodeEnd":388,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/tui/src/integrations/dsh/bundle.rs#L352-L388","documentation":"`remove_from_profile` treats a non-zero exit from `dsh plugin --profile codewhale remove <BUNDLE_PACKAGE_NAME>` as failure and embeds the command's `output_excerpt`. Because removal goes through dsh's documented plugin command (keeping the DSH-owned profile manifest consistent), any dsh/pnpm-side refusal — package not present in the profile, profile dir problems, pnpm failures — surfaces here with dsh's own diagnostic text.","triggerScenarios":"remove-bundle when the bundle package is no longer listed in the `codewhale` profile (already removed manually via `dsh plugin remove`), `$DSH_HOME/profiles/codewhale` is missing or unwritable, or pnpm fails during the remove operation.","commonSituations":"Users removing the plugin by hand in dsh and then running Codewhale's remove-bundle; deleting `$DSH_HOME/profiles/codewhale` manually first; permission or store issues in pnpm; switching machines with a copied-but-incomplete $DSH_HOME.","solutions":["Read the output_excerpt — if it says the package is not installed in the profile, the DSH side is already clean; continue Codewhale-side cleanup","Inspect the profile manifest directly: `dsh.profile.bundles` in `$DSH_HOME/profiles/codewhale/package.json` (Codewhale reads it read-only via profile_bundles)","Fix permissions on the profile dir or pnpm store issues named in the excerpt, then retry remove-bundle","As a last resort, `codewhale integrations dsh remove` deletes Codewhale-owned files without invoking dsh"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// profile_bundles (bundle.rs) reads the DSH-owned manifest read-only\nlet profile_dir = detection.dsh_home.join(\"profiles\").join(dsh::bundle::BUNDLE_PROFILE);\nlet listed = dsh::bundle::profile_bundles(&profile_dir).unwrap_or_default();\nif !listed.iter().any(|name| name == dsh::bundle::BUNDLE_PACKAGE_NAME) {\n    eprintln!(\"bundle not present in the codewhale profile; nothing to remove there\");\n    return Ok(());\n}","typeGuard":"fn bundle_in_profile(profile_dir: &std::path::Path) -> bool {\n    dsh::bundle::profile_bundles(profile_dir)\n        .map(|names| names.iter().any(|n| n == dsh::bundle::BUNDLE_PACKAGE_NAME))\n        .unwrap_or(false)\n}","tryCatchPattern":"match dsh::bundle::remove_from_profile(runner, &detection) {\n    Ok(outcome) => Ok(outcome),\n    Err(e) => {\n        // excerpt says \"not installed in profile\" -> DSH side already clean;\n        // treat as success and continue Codewhale-owned file cleanup\n        let msg = format!(\"{e:#}\");\n        if msg.contains(\"not installed\") { Ok(Default::default()) } else { Err(e) }\n    }\n}","preventionTips":["Remove the bundle through Codewhale's remove-bundle, not by hand in dsh, to keep record and profile in sync","Check the profile manifest (dsh.profile.bundles) before removal attempts","Never pre-delete $DSH_HOME/profiles/codewhale before running remove-bundle"],"tags":["rust","dsh","pnpm","plugin","removal"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}