{"record":{"id":"369d20a520ed9a44","repo":"go-delve/delve","slug":"no-selected-goroutine","errorCode":null,"errorMessage":"no selected goroutine","messagePattern":"no selected goroutine","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/debugger/debugger.go","lineNumber":1957,"sourceCode":"\t\treturn proc.GoroutineStacktrace(d.target.Selected, g, depth, proc.StacktraceOptions(opts))\n\t}\n}\n\n// Ancestors returns the stacktraces for the ancestors of a goroutine.\nfunc (d *Debugger) Ancestors(goroutineID int64, numAncestors, depth int) ([]api.Ancestor, error) {\n\td.targetMutex.Lock()\n\tdefer d.targetMutex.Unlock()\n\n\tif _, err := d.target.Valid(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tg, err := proc.FindGoroutine(d.target.Selected, goroutineID)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif g == nil {\n\t\treturn nil, errors.New(\"no selected goroutine\")\n\t}\n\n\tancestors, err := proc.Ancestors(d.target.Selected, g, numAncestors)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tr := make([]api.Ancestor, len(ancestors))\n\tfor i := range ancestors {\n\t\tr[i].ID = ancestors[i].ID\n\t\tif ancestors[i].Unreadable != nil {\n\t\t\tr[i].Unreadable = ancestors[i].Unreadable.Error()\n\t\t\tcontinue\n\t\t}\n\t\tframes, err := ancestors[i].Stack(depth)\n\t\tif err != nil {\n\t\t\tr[i].Unreadable = fmt.Sprintf(\"could not read ancestor stacktrace: %v\", err)\n\t\t\tcontinue","sourceCodeStart":1939,"sourceCodeEnd":1975,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/service/debugger/debugger.go#L1939-L1975","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nout, err := dbg.Ancestors(-1, 0, 5) // no selected goroutine\n// after\nstate, _ := dbg.GetState(&api.GetStateIn{})\ngoid := state.SelectedGoroutine.ID\nout, err := dbg.Ancestors(goid, 0, 5)","handlingStrategy":"validation","validationCode":"state, _ := dbg.GetState(&api.GetStateIn{})\ngoid := int64(0)\nif state.SelectedGoroutine != nil {\n    goid = state.SelectedGoroutine.ID\n}\nif goid == 0 && requestedID <= 0 {\n    return errors.New(\"need a goroutine: list goroutines and pick one first\")\n}","typeGuard":"func hasTargetGoroutine(state *api.DebuggerState) bool {\n    return state != nil && state.SelectedGoroutine != nil\n}","tryCatchPattern":"out, err := dbg.Ancestors(goid, 0, n)\nif err != nil && err.Error() == \"no selected goroutine\" {\n    gs, _ := dbg.ListGoroutines(&api.ListGoroutinesIn{})\n    goid = gs.Goroutines[0].ID // pick explicitly, then retry\n}","preventionTips":["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"],"tags":["goroutine","state","debugger"],"backgroundTag":"no-selected-goroutine","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}