go-delve/delve · error

error while waiting for task

Error message

error while waiting for task

What it means

trapWait blocks until the debuggee reports a mach message (stop, exit, etc.). If the underlying wait loop receives status 0 — no valid notification — Delve returns "error while waiting for task", meaning the wait for the inferior's event produced nothing usable and the debugger state is indeterminate.

Source

Thrown at pkg/proc/native/proc_darwin.go:345

			_, status, err := dbp.wait(dbp.pid, 0)
			if err != nil {
				return nil, err
			}
			dbp.postExit()
			return nil, proc.ErrProcessExited{Pid: dbp.pid, Status: status.ExitStatus()}

		case C.MACH_RCV_INTERRUPTED:
			halt := dbp.os.halt
			if !halt {
				// Call trapWait again, it seems
				// MACH_RCV_INTERRUPTED is emitted before
				// process natural death _sometimes_.
				continue
			}
			return nil, nil

		case 0:
			return nil, fmt.Errorf("error while waiting for task")
		}

		// In macOS 10.12.1 if we received a notification for a task other than
		// the inferior's task and the inferior's task is no longer valid, this
		// means inferior called execve and its task_t changed.
		if dbp.os.task != task && C.task_is_valid(dbp.os.task) == 0 {
			dbp.os.task = task
			kret := C.reset_exception_ports(dbp.os.task, &dbp.os.exceptionPort, &dbp.os.notificationPort)
			if kret != C.KERN_SUCCESS {
				return nil, fmt.Errorf("could not follow task across exec: %d\n", kret)
			}
		}

		// Since we cannot be notified of new threads on OS X
		// this is as good a time as any to check for them.
		dbp.updateThreadList()
		th, ok := dbp.threads[int(port)]
		if !ok {

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Check whether the inferior was killed externally (dmesg, `ps`) — e.g. SIGKILL from the OS or OOM killer.
  2. Rerun the session; this condition is usually terminal for the debug session.
  3. Avoid running other debug instruments (lldb, Instruments) on the same process simultaneously.
  4. Update Delve — mach wait handling has changed across macOS versions (notably 10.12+).

Example fix

// before
sudo kill -9 <pid>   // externally kills inferior mid-session
// after
deliver signals from within the debugger: (dlv) continue  // then use halt/kill commands
Defensive patterns

Strategy: retry

Validate before calling

// Before continuing, record that the target is alive:
// if the inferior can be SIGKILLed externally, monitor it:
cmd := exec.Command("ps", "-p", strconv.Itoa(pid))
if err := cmd.Run(); err != nil {
    return fmt.Errorf("inferior %d gone before wait", pid)
}

Try / catch

_, err := dbp.trapWait(pid)
if err != nil && strings.Contains(err.Error(), "error while waiting for task") {
    // verify the process wasn't SIGKILLed; restart the session rather than retrying
}

Prevention

When it happens

Trigger: While continue/stepping on macOS, the mach_msg-based wait in trapWait hits its `case 0:` branch: the notification port returned no event, e.g. the task died without delivering an exit notification or the message was consumed unexpectedly.

Common situations: Inferior crashes hard (killed by SIGKILL) so no mach exit notification arrives; debugging over an SSH session where the task is torn down; concurrent debuggers stealing exception messages.

Related errors


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