go-delve/delve · error

internal debugger error: depth check error at instruction %d

Error message

internal debugger error: depth check error at instruction %d: expected depth %d have %d (jump target)
%s

What it means

An internal consistency check in Delve's expression-VM compiler (pkg/proc/evalop/evalcompile.go) failed: when computing operand-stack depths, a jump target instruction was reached with a different stack depth than previously recorded. This is a compiler invariant violation, not something caused by a syntactically valid user expression; it indicates a bug in Delve's opcode generation or a genuinely malformed generated program.

Source

Thrown at pkg/proc/evalop/evalcompile.go:259

// checks that they have enough arguments to execute. For instructions that
// can be reached through multiple paths (because of a jump) it checks that
// all paths reach the instruction with the same stack depth.
// Finally it checks that the stack depth after all instructions have
// executed is equal to endDepth.
func (ctx *compileCtx) depthCheck(endDepth int) error {
	depth := make([]int, len(ctx.ops)+1) // depth[i] is the depth of the stack before i-th instruction
	for i := range depth {
		depth[i] = -1
	}
	depth[0] = 0

	var err error
	checkAndSet := func(j, d int) { // sets depth[j] to d after checking that we can
		if depth[j] < 0 {
			depth[j] = d
		}
		if d != depth[j] {
			err = fmt.Errorf("internal debugger error: depth check error at instruction %d: expected depth %d have %d (jump target)\n%s", j, d, depth[j], Listing(depth, ctx.ops))
		}
	}

	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:

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Update to the latest delve release — check for known fixed issues around evalop/depthCheck
  2. Simplify the expression (remove nesting, casts, calls) until it evaluates, then file a bug with the minimal reproducing expression and `Listing` output embedded in the error
  3. Temporarily replace the failing breakpoint condition with a simpler one and inspect state manually
Defensive patterns

Strategy: try-catch

Try / catch

out, err := evalExpr(userExpr)
if err != nil && strings.HasPrefix(err.Error(), "internal debugger error") {
    // not a user mistake: simplify or report
    out, err = evalExpr(simplify(userExpr))
    log.Printf("delve internal error, please report: %v", err)
}

Prevention

When it happens

Trigger: Calling CompileAST or CompileSet on an expression whose compiled op sequence contains a Jump whose target's depth does not match the depth flowing into it — i.e. a Delve bug in evalop compilation, possibly triggered by an unusual expression shape that hits an untested compiler path.

Common situations: Rare; typically seen after a delve version regression, when testing experimental expression features (e.g. delve.catch, call injection combined with control flow), or when a breakpoint condition exercises a newly added opcode combination.

Related errors


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