{"record":{"id":"655462bb3dc2b4e9","repo":"Hmbown/CodeWhale","slug":"dsh-plugin-add-failed","errorCode":null,"errorMessage":"dsh plugin add {} failed: {}","messagePattern":"dsh plugin add (.+?) failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/integrations/dsh/bundle.rs","lineNumber":338,"sourceCode":"pub(crate) fn install_into_profile(\n    runner: &dyn DshRunner,\n    detection: &DshDetection,\n    app: DshAppBundle,\n    bundle_dir: &Path,\n) -> Result<(PathBuf, Vec<PluginCommandOutcome>)> {\n    let binary = detection\n        .binary\n        .as_ref()\n        .ok_or_else(|| anyhow::anyhow!(\"dsh binary is unknown\"))?;\n    let app_source = app_bundle_source(binary, app)?;\n    let mut outcomes = Vec::new();\n    let app_source_str = app_source.display().to_string();\n    let first = run_dsh_plugin(runner, binary, BUNDLE_PROFILE, &[\"add\", &app_source_str])?;\n    let first_ok = first.success;\n    let first_excerpt = first.output_excerpt.clone();\n    outcomes.push(first);\n    if !first_ok {\n        anyhow::bail!(\n            \"dsh plugin add {} failed: {}\",\n            app.package_name(),\n            first_excerpt\n        );\n    }\n    let bundle_str = bundle_dir.display().to_string();\n    let second = run_dsh_plugin(runner, binary, BUNDLE_PROFILE, &[\"add\", &bundle_str])?;\n    let second_ok = second.success;\n    let second_excerpt = second.output_excerpt.clone();\n    outcomes.push(second);\n    if !second_ok {\n        anyhow::bail!(\"dsh plugin add {BUNDLE_PACKAGE_NAME} failed: {second_excerpt}\");\n    }\n    Ok((app_source, outcomes))\n}\n\npub(crate) fn remove_from_profile(\n    runner: &dyn DshRunner,","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/tui/src/integrations/dsh/bundle.rs#L320-L356","documentation":"`install_into_profile` runs two `dsh plugin --profile codewhale add` commands in order — first the app bundle (`@deepseek-ai/dsh-<app>` linked from the launcher), then the Codewhale bundle so its rows patch last. This error fires when the first add fails: `run_dsh_plugin` reports success=false and the message embeds the command's `output_excerpt`, so dsh/pnpm's own diagnostic text is part of the error. Nothing Codewhale-owned has been added yet at this point.","triggerScenarios":"install-bundle when `dsh plugin --profile codewhale add <app_source_path>` exits non-zero: pnpm registry unreachable, the app source path unreadable, the `codewhale` profile directory not writable, a pnpm store lock conflict, or dsh's plugin subsystem rejecting the package.","commonSituations":"Offline or proxied networks blocking the npm registry; `$DSH_HOME/profiles/codewhale` owned by another user (created under sudo); concurrent pnpm processes holding the store lock; corporate registries requiring auth that pnpm lacks.","solutions":["Read the output_excerpt in the error — it is dsh/pnpm's own failure text and names the real cause","Fix network/registry access (proxy, auth, mirror) and retry; the add is re-runnable","Check permissions on `$DSH_HOME/profiles/codewhale` — it must be writable by the current user","If pnpm's store lock is held, stop other pnpm processes and retry install-bundle"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"let app_source = dsh::bundle::app_bundle_source(binary, app)?; // fails early on bad layout\nif !app_source.is_dir() {\n    eprintln!(\"app bundle source missing: {}\", app_source.display());\n    return Ok(());\n}\n// ensure the profile dir is writable before invoking dsh plugin\nlet profile_dir = detection.dsh_home.join(\"profiles\").join(dsh::bundle::BUNDLE_PROFILE);\nlet writable = std::fs::metadata(&profile_dir).map(|m| !m.permissions().readonly()).unwrap_or(true);","typeGuard":null,"tryCatchPattern":"match dsh::bundle::install_into_profile(runner, &detection, app, &bundle_dir) {\n    Ok((_, outcomes)) => Ok(outcomes),\n    Err(e) => {\n        // the error embeds run_dsh_plugin's output_excerpt; surface it verbatim\n        // and treat transient pnpm failures (network, store lock) as retryable\n        eprintln!(\"plugin add failed (excerpt included in error): {e:#}\");\n        Err(e)\n    }\n}","preventionTips":["Treat the embedded output_excerpt as the primary diagnostic — it is dsh/pnpm's own text","`dsh plugin add` is idempotent, so retrying install-bundle after fixing the excerpt's cause is safe","Keep $DSH_HOME/profiles/codewhale owned by the invoking user (never create it under sudo)","Avoid running other pnpm processes against the same store during install"],"tags":["rust","dsh","pnpm","plugin","network"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}