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

  1. Upgrade delve — pinning call-injection bugs are actively fixed upstream
  2. Avoid function calls in breakpoint conditions; move the call out of the condition and inspect values by stepping instead
  3. 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

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


AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31). Data as JSON: /api/errors/162a2fd5802a2cd8. Report an issue: GitHub.