Hmbown/CodeWhale · error

dsh plugin remove {BUNDLE_PACKAGE_NAME} failed: {}

Error message

dsh plugin remove {BUNDLE_PACKAGE_NAME} failed: {}

What it means

`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.

Source

Thrown at crates/tui/src/integrations/dsh/bundle.rs:370

    Ok((app_source, outcomes))
}

pub(crate) fn remove_from_profile(
    runner: &dyn DshRunner,
    detection: &DshDetection,
) -> Result<PluginCommandOutcome> {
    let binary = detection
        .binary
        .as_ref()
        .ok_or_else(|| anyhow::anyhow!("dsh binary is unknown"))?;
    let outcome = run_dsh_plugin(
        runner,
        binary,
        BUNDLE_PROFILE,
        &["remove", BUNDLE_PACKAGE_NAME],
    )?;
    if !outcome.success {
        anyhow::bail!(
            "dsh plugin remove {BUNDLE_PACKAGE_NAME} failed: {}",
            outcome.output_excerpt
        );
    }
    Ok(outcome)
}

/// Read the dedicated profile's `dsh.profile.bundles` (DSH-owned manifest,
/// read-only) so status can prove the bundle is actually composed.
pub(crate) fn profile_bundles(profile_dir: &Path) -> Option<Vec<String>> {
    let text = std::fs::read_to_string(profile_dir.join("package.json")).ok()?;
    let json: serde_json::Value = serde_json::from_str(&text).ok()?;
    Some(
        json.get("dsh")?
            .get("profile")?
            .get("bundles")?
            .as_array()?
            .iter()

View on GitHub (pinned to 8880682c63)

Solutions

  1. 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
  2. Inspect the profile manifest directly: `dsh.profile.bundles` in `$DSH_HOME/profiles/codewhale/package.json` (Codewhale reads it read-only via profile_bundles)
  3. Fix permissions on the profile dir or pnpm store issues named in the excerpt, then retry remove-bundle
  4. As a last resort, `codewhale integrations dsh remove` deletes Codewhale-owned files without invoking dsh
Defensive patterns

Strategy: try-catch

Validate before calling

// profile_bundles (bundle.rs) reads the DSH-owned manifest read-only
let profile_dir = detection.dsh_home.join("profiles").join(dsh::bundle::BUNDLE_PROFILE);
let listed = dsh::bundle::profile_bundles(&profile_dir).unwrap_or_default();
if !listed.iter().any(|name| name == dsh::bundle::BUNDLE_PACKAGE_NAME) {
    eprintln!("bundle not present in the codewhale profile; nothing to remove there");
    return Ok(());
}

Type guard

fn bundle_in_profile(profile_dir: &std::path::Path) -> bool {
    dsh::bundle::profile_bundles(profile_dir)
        .map(|names| names.iter().any(|n| n == dsh::bundle::BUNDLE_PACKAGE_NAME))
        .unwrap_or(false)
}

Try / catch

match dsh::bundle::remove_from_profile(runner, &detection) {
    Ok(outcome) => Ok(outcome),
    Err(e) => {
        // excerpt says "not installed in profile" -> DSH side already clean;
        // treat as success and continue Codewhale-owned file cleanup
        let msg = format!("{e:#}");
        if msg.contains("not installed") { Ok(Default::default()) } else { Err(e) }
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/c3854ca3baab7944. Report an issue: GitHub.