go-delve/delve · error
internal debugger error: pinning call injection seen before
Error message
internal debugger error: pinning call injection seen before call to %s at instruction %d
What it means
Internal ordering check in the expression compiler: a `CallInjectionComplete` opcode with DoPinning=true was emitted before the required `CallInjectionStartSpecial` (debug pinner) call in the instruction stream, violating the protocol that pinning calls must be preceded by a debug-pinner injection. This indicates generated opcodes are out of order — an internal invariant violation.
Source
Thrown at pkg/proc/evalop/evalcompile.go:279
}
debugPinnerSeen := false
for i, op := range ctx.ops {
npop, npush := op.depthCheck()
if depth[i] < npop {
return fmt.Errorf("internal debugger error: depth check error at instruction %d: expected at least %d have %d\n%s", i, npop, depth[i], Listing(depth, ctx.ops))
}
d := depth[i] - npop + npush
checkAndSet(i+1, d)
switch op := op.(type) {
case *Jump:
checkAndSet(op.Target, d)
case *CallInjectionStartSpecial:
debugPinnerSeen = true
case *CallInjectionComplete:
if op.DoPinning && !debugPinnerSeen {
err = fmt.Errorf("internal debugger error: pinning call injection seen before call to %s at instruction %d", DebugPinnerFunctionName, i)
}
}
if err != nil {
return err
}
}
if depth[len(ctx.ops)] != endDepth {
return fmt.Errorf("internal debugger error: depth check failed: depth at the end is not %d (got %d)\n%s", depth[len(ctx.ops)], endDepth, Listing(depth, ctx.ops))
}
return nil
}
func (ctx *compileCtx) compileAST(t ast.Expr, toplevel bool) error {
switch node := t.(type) {
case *ast.CallExpr:
if f, ok := node.Fun.(*ast.SelectorExpr); ok && ctx.flags&BreakpointCondition != 0 {
const catch = "catch"View on GitHub (pinned to a23773e6c3)
Solutions
- Upgrade delve — pinning call-injection bugs are actively fixed upstream
- Avoid function calls in breakpoint conditions; move the call out of the condition and inspect values by stepping instead
- File a go-delve/delve issue with the minimal expression and the instruction listing
Defensive patterns
Strategy: try-catch
Try / catch
if err != nil && strings.Contains(err.Error(), "pinning call injection") {
// remove call injection from the condition and re-set the breakpoint
setCondition(bp, "true")
log.Printf("pinning injection bug: %v", err)
} Prevention
- Avoid function-call injection inside breakpoint conditions; use plain data comparisons
- When calls are needed, test them with `print` first, then move to conditions
- Track delve releases for call-injection/pinning fixes
When it happens
Trigger: CompileAST/CompileSet compiling an expression that performs a pinning function call injection, where the compiler failed to emit DebugPinnerFunctionName's call-injection before the pinning call — triggered by delve compiler bugs around function calls inside breakpoint conditions or nested call expressions.
Common situations: Seen when using call injection in breakpoint conditions/watch expressions with delve builds where the pinning prelude emission is buggy, or when combining runtime.frame/catch constructs with calls in ways that confuse the compiler.
Related errors
- internal debugger error: depth check error at instruction %d
- internal debugger error: depth check error at instruction %d
- internal debugger error: depth check failed: depth at the en
- internal debugger error: eval program finished without error
- internal debugger error: could not undo injected call during
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/162a2fd5802a2cd8.
Report an issue: GitHub.