go-delve/delve · error

another launch request is in progress

Error message

another launch request is in progress

What it means

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.

Source

Thrown at service/dap/server.go:1411

	s.send(&dap.LaunchResponse{Response: *s.newResponse(request.Request)})
	s.warnAboutTrimpathMaybe()
}

func (s *Session) getPackageDir(pkg string) string {
	cmd := exec.Command("go", "list", "-f", "{{.Dir}}", pkg)
	out, err := cmd.Output()
	if err != nil {
		s.config.log.Debugf("failed to determine package directory for %v: %v\n%s", pkg, err, out)
		return "."
	}
	return string(bytes.TrimSpace(out))
}

// newNoDebugProcess is called from onLaunchRequest (run goroutine) and
// requires holding mu lock. It prepares process exec.Cmd to be started.
func (s *Session) newNoDebugProcess(program string, targetArgs []string, wd string, remoteOut bool, stdinFrom, stdoutTo, stderrTo string) (cmd *exec.Cmd, stdoutReader, stderrReader io.ReadCloser, err error) {
	if s.noDebugProcess != nil {
		return nil, nil, nil, errors.New("another launch request is in progress")
	}

	cmd = exec.Command(program, targetArgs...)
	cmd.Stdin, cmd.Dir = os.Stdin, wd

	if stdinFrom != "" {
		fh, err := os.Open(stdinFrom)
		if err != nil {
			return nil, nil, nil, fmt.Errorf("could not open stdin file: %v", err)
		}
		cmd.Stdin = fh
	}

	if remoteOut {
		if stderrReader, err = cmd.StderrPipe(); err != nil {
			return nil, nil, nil, err
		}

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Disconnect (or restart via the DAP 'restart' flow) before issuing another launch request on the same session
  2. Serialize launch requests in the client: wait for the response to the first launch before sending a second
  3. Inspect why the previous noDebugProcess was never cleared (e.g. a failed start or missing cleanup) and fix the cleanup path
  4. Use a fresh DAP server session per launch if multiple concurrent targets are needed

Example fix

// before: client sends launch twice over one connection
sendLaunch(req); sendLaunch(req) // -> 'another launch request is in progress'
// after: await first response, then relaunch
await client.launch(req1)
await client.disconnectRequest()
await client.launch(req2)
Defensive patterns

Strategy: validation

Validate before calling

// client-side guard: only one in-flight launch per DAP session
if session.launchInFlight { return errors.New("launch already pending") }
session.launchInFlight = true
launch(req).finally(func(){ session.launchInFlight = false })

Try / catch

// catch and surface, do not retry blindly
if strings.Contains(err.Error(), "another launch request is in progress") {
    // disconnect and start a new session before relaunching
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31). Data as JSON: /api/errors/fe45ae785d4790f7. Report an issue: GitHub.