{"record":{"id":"fe45ae785d4790f7","repo":"go-delve/delve","slug":"another-launch-request-is-in-progress","errorCode":null,"errorMessage":"another launch request is in progress","messagePattern":"another launch request is in progress","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/dap/server.go","lineNumber":1411,"sourceCode":"\ts.send(&dap.LaunchResponse{Response: *s.newResponse(request.Request)})\n\ts.warnAboutTrimpathMaybe()\n}\n\nfunc (s *Session) getPackageDir(pkg string) string {\n\tcmd := exec.Command(\"go\", \"list\", \"-f\", \"{{.Dir}}\", pkg)\n\tout, err := cmd.Output()\n\tif err != nil {\n\t\ts.config.log.Debugf(\"failed to determine package directory for %v: %v\\n%s\", pkg, err, out)\n\t\treturn \".\"\n\t}\n\treturn string(bytes.TrimSpace(out))\n}\n\n// newNoDebugProcess is called from onLaunchRequest (run goroutine) and\n// requires holding mu lock. It prepares process exec.Cmd to be started.\nfunc (s *Session) newNoDebugProcess(program string, targetArgs []string, wd string, remoteOut bool, stdinFrom, stdoutTo, stderrTo string) (cmd *exec.Cmd, stdoutReader, stderrReader io.ReadCloser, err error) {\n\tif s.noDebugProcess != nil {\n\t\treturn nil, nil, nil, errors.New(\"another launch request is in progress\")\n\t}\n\n\tcmd = exec.Command(program, targetArgs...)\n\tcmd.Stdin, cmd.Dir = os.Stdin, wd\n\n\tif stdinFrom != \"\" {\n\t\tfh, err := os.Open(stdinFrom)\n\t\tif err != nil {\n\t\t\treturn nil, nil, nil, fmt.Errorf(\"could not open stdin file: %v\", err)\n\t\t}\n\t\tcmd.Stdin = fh\n\t}\n\n\tif remoteOut {\n\t\tif stderrReader, err = cmd.StderrPipe(); err != nil {\n\t\t\treturn nil, nil, nil, err\n\t\t}\n","sourceCodeStart":1393,"sourceCodeEnd":1429,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/service/dap/server.go#L1393-L1429","documentation":"This error is thrown by newNoDebugProcess in the DAP server when a launch request with noDebug=true arrives while the session already holds a prepared no-debug process (s.noDebugProcess != nil). The session only supports one no-debug launch at a time, so a second concurrent or repeated launch is rejected. It guards against spawning multiple child processes from the same session.","triggerScenarios":"Sending two 'launch' requests (noDebug mode) to the same DAP session without disconnecting between them; a client auto-restarting a launch while the previous launch request's run goroutine is still active; concurrent launch requests racing before mu-protected cleanup runs.","commonSituations":"IDE restart/relaunch configurations that fire a second launch before the first session is disposed; misbehaving DAP clients that do not honor the 'restart' flow; testing harnesses that reuse one DAP connection for multiple launches.","solutions":["Disconnect (or restart via the DAP 'restart' flow) before issuing another launch request on the same session","Serialize launch requests in the client: wait for the response to the first launch before sending a second","Inspect why the previous noDebugProcess was never cleared (e.g. a failed start or missing cleanup) and fix the cleanup path","Use a fresh DAP server session per launch if multiple concurrent targets are needed"],"exampleFix":"// before: client sends launch twice over one connection\nsendLaunch(req); sendLaunch(req) // -> 'another launch request is in progress'\n// after: await first response, then relaunch\nawait client.launch(req1)\nawait client.disconnectRequest()\nawait client.launch(req2)","handlingStrategy":"validation","validationCode":"// client-side guard: only one in-flight launch per DAP session\nif session.launchInFlight { return errors.New(\"launch already pending\") }\nsession.launchInFlight = true\nlaunch(req).finally(func(){ session.launchInFlight = false })","typeGuard":null,"tryCatchPattern":"// catch and surface, do not retry blindly\nif strings.Contains(err.Error(), \"another launch request is in progress\") {\n    // disconnect and start a new session before relaunching\n}","preventionTips":["Always send a disconnect request before a new launch on the same connection","Await the launch response before issuing further lifecycle requests","Use the DAP restart flow instead of launch-disconnect-launch for relaunches"],"tags":["dap","launch","concurrency","go"],"backgroundTag":"launch-already-in-progress","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}