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)
continueView on GitHub (pinned to a23773e6c3)
Solutions
- Pass a valid goroutineID obtained from ListGoroutines/Stacktrace
- Select a goroutine first (terminal `goroutine N` / RPC SelectGoroutine) before calling
- 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
- Refresh goroutine lists after each continue/step; IDs go stale after exits
- Pass an explicit goroutineID rather than relying on selection state
- Guard UI code paths that assume a selected goroutine exists
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
- selected goroutine not running
- next while nexting
- could not determine running goroutine for thread %#x current
- hardware breakpoints exhausted
- break on read only not supported
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/369d20a520ed9a44.
Report an issue: GitHub.