go-delve/delve · error
could not get panic: %v
Error message
could not get panic: %v
What it means
During an injected function call that panicked, Delve enters the runtime's debug call protocol state debugCallRegReadPanic and must read the panic value (an interface{}) off the goroutine stack at SP+archoff (offset depends on architecture). When readStackVariable fails — because the type 'interface {}' cannot be found in DWARF, the stack memory is unreadable, or the value fails to load under the current load config — the call's error is set to "could not get panic: %v". The injected call cannot report which panic occurred, so the operation is aborted with the wrapped cause.
Source
Thrown at pkg/proc/fncall.go:954
fncall.addrsToPin = slices.Compact(fncall.addrsToPin)
return false // will continue with evalop.CallInjectionComplete2
}
callInjectionComplete2(callScope, bi, fncall, regs, thread)
case debugCallRegReadPanic: // 2
// read panic value from stack
stack.callInjectionContinue = true
archoff := uint64(0)
if bi.Arch.Name == "arm64" || bi.Arch.Name == "loong64" {
archoff = 8
} else if bi.Arch.Name == "ppc64le" {
archoff = 32
}
fncall.panicvar, err = readStackVariable(p, thread, regs, archoff, "interface {}", callScope.callCtx.retLoadCfg)
if err != nil {
fncall.err = fmt.Errorf("could not get panic: %v", err)
break
}
fncall.panicvar.Name = "~panic"
default:
// Got an unknown protocol register value, this is probably bad but the safest thing
// possible is to ignore it and hope it didn't matter.
stack.callInjectionContinue = true
fncallLog("unknown value of protocol register %#x", regval)
}
return false
}
func callInjectionComplete2(callScope *EvalScope, bi *BinaryInfo, fncall *functionCallState, regs Registers, thread Thread) {
// Store the stack span of the currently running goroutine (which in Go >=
// 1.15 might be different from the original injection goroutine) so that
// later on we can use it to perform the escapeCheckView on GitHub (pinned to a23773e6c3)
Solutions
- Inspect the wrapped cause (%v) to distinguish memory-read failure from missing DWARF type; fix that underlying issue first.
- Rebuild the target binary without stripping and with a supported Go version so 'interface {}' DWARF type is present.
- Increase LoadConfig limits (MaxStringLen, MaxStructFields, MaxRecvSteps) when the panic value is truncated/unreadable.
- Re-attach or restart the target if the process exited or memory state is inconsistent.
- Update Delve to match your Go version — debug-call protocol offsets change between releases.
Example fix
// before (dlv config limits panic value load) dlv config max-string-len 64 // after # start delve with larger limits so the panic interface value loads dlv debug --init init.txt # init.txt: config max-string-len 4096 config max-array-values 512
Defensive patterns
Strategy: try-catch
Validate before calling
// client-side (terminal): ensure binary has full DWARF and limits are generous dlv> config max-string-len 4096 dlv> config max-array-values 512 dlv> sources main.go // confirms binary has debug info
Type guard
// guard injected-call results before use
type callResult struct{ Err error; PanicVar *proc.Variable }
func panicReadable(r callResult) bool {
return r.Err == nil || !strings.HasPrefix(r.Err.Error(), "could not get panic:")
} Try / catch
// wrap expression evaluation and detect this family
v, err := dbg.EvalVariable(scope, expr, cfg)
if err != nil && strings.Contains(err.Error(), "could not get panic:") {
// injected call panicked but panic value unreadable:
// restart session or raise LoadConfig limits and retry once
} Prevention
- Build targets with full debug info (no -trimpath/-ldflags="-s -w" stripping).
- Keep Delve version in sync with the Go toolchain version used to build the target.
- Raise max-string-len/max-array-values before injecting calls that can panic.
- Avoid injecting calls that can panic; validate inputs at the breakpoint first.
- Watch for target-thread death during injection; re-attach if state looks inconsistent.
When it happens
Trigger: Running a function call injection (e.g. via the 'call' command or expression evaluation) where the called function panics; the debugCallRegReadPanic protocol step then fails to read the panic value: DWARF info lacks the 'interface {}' type, the target's stack memory is unreadable (exited/corrupt process), or loadValue hits the MaxStringLen/MaxArrayRestriction limits of retLoadCfg.
Common situations: Debugging a stripped or partially-optimized binary where runtime type info is incomplete; target process dies mid-call-injection; extremely large string/struct in the panic value exceeding LoadConfig limits; debugging across Go runtime versions that changed the debug-call protocol stack layout.
Related errors
- could not restore LR: %v
- could not set call receiver: %v
- function %s not found
- unexpected return type for mallocgc call: %v
- could not determine running goroutine for thread %#x current
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/04d6f083ae34d54f.
Report an issue: GitHub.