{"record":{"id":"a1a1ef64fb71fd52","repo":"go-delve/delve","slug":"could-not-determine-running-goroutine-for-thread","errorCode":null,"errorMessage":"could not determine running goroutine for thread %#x currently executing the function call injection protocol: %v","messagePattern":"could not determine running goroutine for thread %#x currently executing the function call injection protocol: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/fncall.go","lineNumber":1202,"sourceCode":"\n\t\tfncallLog(\"step for injection on goroutine %d (current) thread=%d (location %s)\", g.ID, thread.ThreadID(), loc.Fn.Name)\n\t\tt.currentThread = thread\n\t\tcallinj.evalStack.resume(g)\n\t\tif !callinj.evalStack.callInjectionContinue {\n\t\t\terr := finishEvalExpressionWithCalls(t, g, callinj.evalStack)\n\t\t\tif err != nil {\n\t\t\t\treturn done, err\n\t\t\t}\n\t\t\tdone = true\n\t\t}\n\t}\n\treturn done, nil\n}\n\nfunc findCallInjectionStateForThread(t *Target, thread Thread) (*G, *callInjection, error) {\n\tg, err := GetG(thread)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"could not determine running goroutine for thread %#x currently executing the function call injection protocol: %v\", thread.ThreadID(), err)\n\t}\n\tfncallLog(\"findCallInjectionStateForThread thread=%d goroutine=%d\", thread.ThreadID(), g.ID)\n\tnotfound := func() error {\n\t\treturn fmt.Errorf(\"could not recover call injection state for goroutine %d (thread %d)\", g.ID, thread.ThreadID())\n\t}\n\tcallinj := t.fncallForG[g.ID]\n\tif callinj != nil {\n\t\tif callinj.evalStack == nil {\n\t\t\treturn nil, nil, notfound()\n\t\t}\n\t\treturn g, callinj, nil\n\t}\n\n\t// In Go 1.15 and later the call injection protocol will switch to a\n\t// different goroutine.\n\t// Here we try to recover the injection goroutine by checking the injection\n\t// thread.\n","sourceCodeStart":1184,"sourceCodeEnd":1220,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/fncall.go#L1184-L1220","documentation":"During the function call injection protocol Delve must know which goroutine is running on the thread that hit the injected-call breakpoint, because call-injection state is tracked per goroutine (t.fncallForG). findCallInjectionStateForThread calls GetG(thread) to recover the goroutine; if that fails (runtime structures unreadable, thread not executing Go code, goroutine exited), it throws this error wrapping the underlying GetG failure.","triggerScenarios":"GetG fails on a thread that is mid-call-injection — e.g. the goroutine executing the injected call has exited, the thread is running non-Go code (cgo or runtime), or the G struct cannot be read from process memory at the moment the breakpoint fires.","commonSituations":"Injected call triggers while the target goroutine has died or the thread left Go code; attaching to a process whose runtime state is unreadable; race where the runtime schedules the thread away between injection steps; debugging stripped binaries where runtime symbols are missing.","solutions":["Retry the call injection; transient scheduling races often resolve on a second attempt.","Ensure the thread is executing Go code (not cgo/runtime) when the call completes; avoid injecting calls that can call into C.","Verify the binary has full Go runtime symbol/DWARF information (don't strip; build with default flags).","Update Delve; check github.com/go-delve/delve for known GetG/GetG issues with your Go version."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := injectCall(g, fn)\nif err != nil && strings.Contains(err.Error(), \"could not determine running goroutine\") {\n    // goroutine may have exited or thread left Go code; reschedule on a live goroutine\n    return retryOnLiveGoroutine(fn)\n}\nreturn err","preventionTips":["Don't inject calls that can run cgo or non-Go code","Don't inject calls on goroutines about to exit","Ensure binaries keep runtime symbols (no stripping)","Retry transient failures once before giving up"],"tags":["go","debugger","goroutine","function-call-injection"],"backgroundTag":"goroutine-lookup-failed","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}