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
- Check whether the inferior was killed externally (dmesg, `ps`) — e.g. SIGKILL from the OS or OOM killer.
- Rerun the session; this condition is usually terminal for the debug session.
- Avoid running other debug instruments (lldb, Instruments) on the same process simultaneously.
- 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
- Never SIGKILL the inferior from outside a live debug session.
- Don't run competing debug tooling that consumes mach exception messages.
- Keep Delve updated for your macOS release.
- Treat this error as terminal: check the process and relaunch.
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
- could not resume task
- could not attach to %d
- could not follow task across exec: %d
- error waiting for thread stop %d
- could not set pc
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/739ad75c76ab45f1.
Report an issue: GitHub.