{"record":{"id":"19b82423914359fe","repo":"Hmbown/CodeWhale","slug":"current-codewhale-route-cannot-be-carried-by-dsh","errorCode":null,"errorMessage":"current Codewhale route cannot be carried by DSH: {reason}","messagePattern":"current Codewhale route cannot be carried by DSH: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/integrations/dsh/mod.rs","lineNumber":329,"sourceCode":"    pub(crate) profile: String,\n    pub(crate) launch_command: String,\n    pub(crate) env_exports: Vec<(String, String)>,\n    pub(crate) shadowing_namespaces: Vec<String>,\n    pub(crate) disclosures: Vec<String>,\n}\n\npub(crate) fn plan(\n    paths: &DshPaths,\n    detection: &DshDetection,\n    identity: &CodewhaleRouteIdentity,\n    profile: &str,\n    allow_full_access: bool,\n    skin: bool,\n) -> Result<DshPlan> {\n    let mapped = map_identity(identity, allow_full_access);\n    let overlay_text = render_overlay(&mapped).ok_or_else(|| match &mapped.adapter {\n        DshAdapter::Unsupported { reason } => {\n            anyhow::anyhow!(\"current Codewhale route cannot be carried by DSH: {reason}\")\n        }\n        _ => anyhow::anyhow!(\"overlay could not be rendered\"),\n    })?;\n    let overlay_sha256 = sha256_hex(overlay_text.as_bytes());\n    let mut disclosures = mapped.disclosures.clone();\n    let shadowing = shadowing_namespaces(detection);\n    if !shadowing.is_empty() {\n        disclosures.push(format!(\n            \"$DSH_HOME/settings.yaml has [{}] sections; DSH layers those over the overlay per field, so the saved DSH selection can shadow the pinned identity until you clear it in DSH.\",\n            shadowing.join(\", \")\n        ));\n    }\n    if !detection.profiles.iter().any(|p| p == profile) {\n        disclosures.push(format!(\n            \"DSH profile `{profile}` is not initialized yet; dsh will create $DSH_HOME/profiles/{profile} on first launch (its own documented behavior).\"\n        ));\n    }\n    if skin {","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/tui/src/integrations/dsh/mod.rs#L311-L347","documentation":"`dsh::plan` maps the Codewhale route identity onto a DSH adapter via `map_identity` before rendering the overlay; when mapping yields `DshAdapter::Unsupported`, `render_overlay` returns None and this error surfaces with the adapter's reason. Grounded reasons (identity.rs:202-268): the base_url is not structural (e.g. embeds userinfo), the route speaks the OpenAI Responses protocol, or the Anthropic Messages protocol — the adapter only carries DeepSeek-native routes and `openai-completions` hand-declared routes.","triggerScenarios":"connect/plan/update while the active Codewhale route is an OpenAI Responses-protocol provider, an Anthropic Messages-protocol provider, or a base_url with embedded credentials — none of which the DSH overlay format can express. DeepSeek providers over ChatCompletions and generic ChatCompletions providers map fine.","commonSituations":"Pointing Codewhale at an Anthropic or OpenAI Responses provider and then trying to connect DSH; self-hosted gateways that expose the Responses API; base_urls containing user:pass@ style prefixes.","solutions":["Switch the active Codewhale route to a provider the adapter carries: DeepSeek (deepseek/deepseek-cn) or any ChatCompletions-compatible provider","Remove credentials embedded in the base_url — put them in the provider's key env var instead","Preview mappability without side effects: `codewhale integrations dsh plan` fails with the same reason before anything is written","If you need Responses/Anthropic routes, do not connect DSH through Codewhale; run dsh with its own configuration"],"exampleFix":"// before — plan and fail late\nlet plan = dsh::plan(&paths, &detection, &identity, &profile, allow_full_access, skin)?;\n\n// after — check mappability first (identity.rs provides MappedIdentity::mappable)\nlet mapped = dsh::map_identity(&identity, allow_full_access);\nif !mapped.mappable() {\n    if let dsh::DshAdapter::Unsupported { reason } = &mapped.adapter {\n        eprintln!(\"route not carryable by DSH: {reason}\");\n    }\n    return Ok(());\n}\nlet plan = dsh::plan(&paths, &detection, &identity, &profile, allow_full_access, skin)?;","handlingStrategy":"type-guard","validationCode":"let mapped = dsh::map_identity(&identity, allow_full_access);\nif !mapped.mappable() {\n    if let dsh::DshAdapter::Unsupported { reason } = &mapped.adapter {\n        eprintln!(\"this route cannot be carried by DSH: {reason}\");\n    }\n    return Ok(());\n}\nlet plan = dsh::plan(&paths, &detection, &identity, &profile, allow_full_access, skin)?;","typeGuard":"fn route_carryable(identity: &dsh::CodewhaleRouteIdentity, allow_full_access: bool) -> bool {\n    dsh::map_identity(identity, allow_full_access).mappable() // identity.rs:94\n}","tryCatchPattern":"// plan() only fails for Unsupported after map_identity; pre-check mappable()\n// and render the reason as guidance, reserving the bail for truly unexpected\n// render failures.","preventionTips":["Check mappability with `codewhale integrations dsh plan` before promising DSH connectivity in the UI","Keep the active route on DeepSeek or ChatCompletions-compatible providers when DSH integration matters","Never put credentials in base_url — structural URLs are a hard requirement of the overlay"],"tags":["rust","dsh","provider","protocol","adapter"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}