{"record":{"id":"2a5f8d9e0a21d7f4","repo":"zed-industries/zed","slug":"cannot-have-two-different-hosts-in-debug-configura","errorCode":null,"errorMessage":"Cannot have two different hosts in debug configuration","messagePattern":"Cannot have two different hosts in debug configuration","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/dap_adapters/src/python.rs","lineNumber":377,"sourceCode":"                )\n            })\n            .unwrap_or_else(|| {\n                (\n                    config\n                        .config\n                        .get(\"port\")\n                        .and_then(|port| port.as_u64().map(|p| p as u16)),\n                    config.config.get(\"host\").and_then(|host| host.as_str()),\n                )\n            });\n\n        let is_attach_with_connect = if config\n            .config\n            .get(\"request\")\n            .is_some_and(|val| val.as_str().is_some_and(|request| request == \"attach\"))\n        {\n            if tcp_connection.host.is_some() && config_host.is_some() {\n                bail!(\"Cannot have two different hosts in debug configuration\")\n            } else if tcp_connection.port.is_some() && config_port.is_some() {\n                bail!(\"Cannot have two different ports in debug configuration\")\n            }\n\n            if let Some(hostname) = config_host {\n                tcp_connection.host = Some(hostname.parse().context(\"invalid IP address\")?);\n            }\n            tcp_connection.port = config_port;\n            DebugpyLaunchMode::AttachWithConnect { host: config_host }\n        } else {\n            DebugpyLaunchMode::Normal\n        };\n\n        let (host, port, timeout) = crate::configure_tcp_connection(tcp_connection).await?;\n\n        let python_path = if let Some(toolchain) = python_from_toolchain {\n            Some(toolchain)\n        } else {","sourceCodeStart":359,"sourceCodeEnd":395,"githubUrl":"https://github.com/zed-industries/zed/blob/f4178619acd0d47ea1f76a2025c42962c6d6638c/crates/dap_adapters/src/python.rs#L359-L395","documentation":"debugpy attach validation in Zed's Python adapter: when `request` is `\"attach\"` and both the task-level `tcp_connection` block already carry a `host` AND the adapter `config` object also has a `\"host\"` key, Zed cannot tell which host to dial and bails instead of guessing (python.rs:377). This guards against silently attaching to the wrong machine.","triggerScenarios":"A Zed debug task with `adapter: \"Python\"`, `tcp_connection: { \"host\": \"127.0.0.1\", \"port\": 5678 }`, and a `config` that also contains `\"host\": \"localhost\"` under an attach request. Both sources being non-null on an attach request is the exact trigger.","commonSituations":"Pasting a VS Code launch.json (which puts host/port inside the config) into a Zed debug configuration that already declares tcp_connection; incrementally migrating attach configs and leaving the old host key behind.","solutions":["Remove `host` from the `config` object and keep it only in `tcp_connection` (or the reverse) so exactly one source defines it.","For local debugpy attach, prefer `\"tcp_connection\": { \"host\": \"127.0.0.1\", \"port\": 5678 }` with `\"request\": \"attach\"` and no host inside config."],"exampleFix":"// before (debug.json)\n{\n  \"adapter\": \"Python\",\n  \"request\": \"attach\",\n  \"tcp_connection\": { \"host\": \"127.0.0.1\", \"port\": 5678 },\n  \"config\": { \"host\": \"localhost\", \"port\": 5678 }\n}\n\n// after\n{\n  \"adapter\": \"Python\",\n  \"request\": \"attach\",\n  \"tcp_connection\": { \"host\": \"127.0.0.1\", \"port\": 5678 },\n  \"config\": { \"request\": \"attach\" }\n}","handlingStrategy":"validation","validationCode":"// reject attach configs that define host in two places, before starting a session\nlet has_tcp_host = task.tcp_connection.as_ref().is_some_and(|t| t.host.is_some());\nlet has_config_host = task.config.get(\"request\") == Some(\"attach\") && task.config.get(\"host\").is_some();\nif has_tcp_host && has_config_host {\n    return Err(anyhow!(\"remove `host` from either tcp_connection or config\"));\n}","typeGuard":"fn defines_host_once(tcp: &Option<TcpConnection>, config: &serde_json::Value) -> bool {\n    let in_tcp = tcp.as_ref().is_some_and(|t| t.host.is_some());\n    let in_config = config.get(\"host\").is_some_and(|v| !v.is_null());\n    !(in_tcp && in_config)\n}","tryCatchPattern":"Catch before session start and print both offending values (tcp_connection.host vs config.host) so the user sees the conflict instead of a generic failure.","preventionTips":["Adopt a convention: connection transport fields live only in tcp_connection; adapter behavior fields live only in config.","Lint debug configs on save for duplicate host/port keys.","When migrating from VS Code launch.json, delete transport keys from the pasted config."],"tags":["debugger","debugpy","configuration","attach","zed"],"backgroundTag":"conflicting-config-values","analyzedSha":"f4178619acd0d47ea1f76a2025c42962c6d6638c","analyzedAt":"2026-08-20T19:29:52.058Z","contentChangedAt":"2026-08-20T19:29:52.058Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}