go-delve/delve · error

no selected goroutine

Error message

no selected goroutine

What it means

Some goroutine-scoped operations (here, retrieving goroutine ancestors) require a goroutine to operate on. When FindGoroutine returns nil (no goroutine with the requested ID exists, or no goroutine ID was given and none is currently selected), Delve returns this error instead of silently choosing a target.

Source

Thrown at service/debugger/debugger.go:1957

		return proc.GoroutineStacktrace(d.target.Selected, g, depth, proc.StacktraceOptions(opts))
	}
}

// Ancestors returns the stacktraces for the ancestors of a goroutine.
func (d *Debugger) Ancestors(goroutineID int64, numAncestors, depth int) ([]api.Ancestor, error) {
	d.targetMutex.Lock()
	defer d.targetMutex.Unlock()

	if _, err := d.target.Valid(); err != nil {
		return nil, err
	}

	g, err := proc.FindGoroutine(d.target.Selected, goroutineID)
	if err != nil {
		return nil, err
	}
	if g == nil {
		return nil, errors.New("no selected goroutine")
	}

	ancestors, err := proc.Ancestors(d.target.Selected, g, numAncestors)
	if err != nil {
		return nil, err
	}

	r := make([]api.Ancestor, len(ancestors))
	for i := range ancestors {
		r[i].ID = ancestors[i].ID
		if ancestors[i].Unreadable != nil {
			r[i].Unreadable = ancestors[i].Unreadable.Error()
			continue
		}
		frames, err := ancestors[i].Stack(depth)
		if err != nil {
			r[i].Unreadable = fmt.Sprintf("could not read ancestor stacktrace: %v", err)
			continue

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Pass a valid goroutineID obtained from ListGoroutines/Stacktrace
  2. Select a goroutine first (terminal `goroutine N` / RPC SelectGoroutine) before calling
  3. Check that the goroutine still exists; re-list goroutines if the target continued running

Example fix

// before
out, err := dbg.Ancestors(-1, 0, 5) // no selected goroutine
// after
state, _ := dbg.GetState(&api.GetStateIn{})
goid := state.SelectedGoroutine.ID
out, err := dbg.Ancestors(goid, 0, 5)
Defensive patterns

Strategy: validation

Validate before calling

state, _ := dbg.GetState(&api.GetStateIn{})
goid := int64(0)
if state.SelectedGoroutine != nil {
    goid = state.SelectedGoroutine.ID
}
if goid == 0 && requestedID <= 0 {
    return errors.New("need a goroutine: list goroutines and pick one first")
}

Type guard

func hasTargetGoroutine(state *api.DebuggerState) bool {
    return state != nil && state.SelectedGoroutine != nil
}

Try / catch

out, err := dbg.Ancestors(goid, 0, n)
if err != nil && err.Error() == "no selected goroutine" {
    gs, _ := dbg.ListGoroutines(&api.ListGoroutinesIn{})
    goid = gs.Goroutines[0].ID // pick explicitly, then retry
}

Prevention

When it happens

Trigger: Calling Debugger.Ancestors (RPC2) with goroutineID <= 0 while no goroutine is selected in the target, or with a goroutineID that does not match any live goroutine.

Common situations: Querying ancestors before the program has any selected goroutine (e.g. immediately after attach); using a stale goroutine ID after the goroutine exited; frontends not syncing the selected goroutine state.

Related errors


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