go-delve/delve · error

%v also %v

Error message

%v also %v

What it means

In the Windows backend's Attach, Delve first tries to attach to the already-running process (often in response to a race where the target exited or was spawned by another mechanism — the recorded aperr from that earlier attempt). If _DebugActiveProcess then also fails, both errors are combined with "%v also %v" so the developer sees the original attach failure plus the DebugActiveProcess failure.

Source

Thrown at pkg/proc/native/proc_windows.go:173

	}

	if waitFor.Valid() {
		var err error
		pid, err = WaitFor(waitFor)
		if err != nil {
			return nil, err
		}
	}

	dbp := newProcess(pid)
	var err error
	dbp.execPtraceFunc(func() {
		// TODO: Probably should have SeDebugPrivilege before starting here.
		err = _DebugActiveProcess(uint32(pid))
	})
	if err != nil {
		if aperr != nil {
			return nil, fmt.Errorf("%v also %v", err, aperr)
		}
		return nil, err
	}
	exepath, err := findExePath(pid)
	if err != nil {
		return nil, err
	}
	tgt, err := dbp.initialize(exepath, []string{})
	if err != nil {
		detachWithoutGroup(dbp, true)
		return nil, err
	}
	return tgt, nil
}

// acquireDebugPrivilege acquires the debug privilege which is needed to
// debug other user's processes.
// See:

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Read the second error (the DebugActiveProcess one) for the root cause; the first is the earlier attach attempt's error.
  2. Re-check that the PID is still alive before attaching (`tasklist /FI "PID eq <pid>"`).
  3. Run Delve elevated (Administrator) so SeDebugPrivilege is available.
  4. Retry attach promptly after launching the target to avoid the exit race.

Example fix

// before
dlv attach 4242
// error: exit status 1 also Access is denied.
// after
# run as Administrator, and verify PID first
tasklist /FI "PID eq 4242"
dlv attach 4242
Defensive patterns

Strategy: try-catch

Validate before calling

// windows
out, _ := exec.Command("tasklist", "/FI", fmt.Sprintf("PID eq %d", pid)).Output()
alive := strings.Contains(string(out), strconv.Itoa(pid))
_ = alive // attach only if the pid still exists

Try / catch

_, err := dbg.Attach(pid, []string{})
if err != nil {
    var ex proc.ErrProcessExited
    if errors.As(err, &ex) {
        // target died during attach; restart it and re-attach
    } else {
        // privilege or access problem; check the second error in the message
    }
}

Prevention

When it happens

Trigger: Calling debugger Attach(pid) on Windows where an initial attach attempt failed (aperr set) and the subsequent _DebugActiveProcess call also fails — e.g. the process exited between attempts, or the caller lacks debug privileges.

Common situations: Attaching to a process that just crashed or exited (race condition); attaching without SeDebugPrivilege to a process owned by another user; attaching to a protected/PPL process; a stale PID from a wrapper script.

Related errors


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