{"record":{"id":"6494d7070ee73980","repo":"zed-industries/zed","slug":"no-process-selected-with-config-that-contains","errorCode":null,"errorMessage":"No process selected with config that contains {}","messagePattern":"No process selected with config that contains (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/debugger_ui/src/session/running.rs","lineNumber":1102,"sourceCode":"                let (tx, rx) = futures::channel::oneshot::channel::<Option<i32>>();\n\n                let weak_workspace_clone = weak_workspace.clone();\n                weak_workspace.update_in(cx, |workspace, window, cx| {\n                    let project = workspace.project().clone();\n                    workspace.toggle_modal(window, cx, |window, cx| {\n                        AttachModal::new(\n                            ModalIntent::ResolveProcessId(Some(tx)),\n                            weak_workspace_clone,\n                            project,\n                            true,\n                            window,\n                            cx,\n                        )\n                    });\n                }).ok();\n\n                let Some(process_id) = rx.await.ok().flatten() else {\n                    bail!(\"No process selected with config that contains {}\", PROCESS_ID_PLACEHOLDER.as_str())\n                };\n\n                Self::substitute_process_id_in_config(&mut config, process_id);\n            }\n\n            let request_type = match dap_registry\n                .adapter(&adapter)\n                .with_context(|| format!(\"{adapter}: is not a valid adapter name\")) {\n                    Ok(adapter) => adapter.request_kind(&config).await,\n                    Err(e) => Err(e)\n                };\n\n\n            let config_is_valid = request_type.is_ok();\n            let mut extra_config = Value::Null;\n            let build_output = if let Some(build) = build {\n                let (task_template, locator_name) = match build {\n                    BuildTaskDefinition::Template {","sourceCodeStart":1084,"sourceCodeEnd":1120,"githubUrl":"https://github.com/zed-industries/zed/blob/f4178619acd0d47ea1f76a2025c42962c6d6638c/crates/debugger_ui/src/session/running.rs#L1084-L1120","documentation":"Attach-to-process flow: when the resolved debug config still contains the processId placeholder, Zed opens the AttachModal with a oneshot channel to receive a PID; if the modal is dismissed (or nothing is selected) the channel yields None and the session aborts with this message before substituting the PID (running.rs:1102).","triggerScenarios":"A debug config containing the `{processId}` placeholder under an attach request, and the user cancels the process picker, or the picker's filtered list is empty so no PID is ever sent through the channel.","commonSituations":"Target process exits before selection; the process belongs to another user and is filtered out by permissions; users pressing Esc expecting attach to proceed; headless/automation contexts where no one answers the modal.","solutions":["Re-run the attach and actually select a process in the modal.","Confirm the target process is still running and visible to the picker (on Linux/macOS, same-user processes or elevated permissions).","Skip the modal by putting a concrete `\"processId\": <pid>` in the config instead of the placeholder.","For services with fixed ports, prefer a `tcp_connection` attach instead of processId."],"exampleFix":"// before (debug.json — triggers picker; cancel -> error)\n{\n  \"adapter\": \"Python\",\n  \"request\": \"attach\",\n  \"config\": { \"processId\": \"${0}\" }\n}\n\n// after (explicit pid, no modal)\n{\n  \"adapter\": \"Python\",\n  \"request\": \"attach\",\n  \"config\": { \"processId\": 41235 }\n}","handlingStrategy":"try-catch","validationCode":"// only prompt for a PID when the config actually needs one\nlet needs_pid = config.to_string().contains(PROCESS_ID_PLACEHOLDER.as_str());\nif !needs_pid {\n    // skip the attach modal entirely\n    return Ok(config);\n}","typeGuard":null,"tryCatchPattern":"Await the PID channel and branch: `match rx.await.ok().flatten() { Some(pid) => substitute(pid), None => return Err(UserCancelled) }` — model dismissal as a distinct cancel error rather than a generic failure, so UI can stay quiet.","preventionTips":["Use a fixed processId or port-based attach for services with a known PID/port.","Ensure the target process is running and selectable before starting attach.","Treat picker cancellation as user intent, never retry it automatically."],"tags":["debugger","attach","process-id","modal","zed"],"backgroundTag":"missing-process-id","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"}