go-delve/delve · error
internal debugger error: depth check failed: depth at the en
Error message
internal debugger error: depth check failed: depth at the end is not %d (got %d) %s
What it means
Final check of the expression compiler's depth verification (depthCheck in pkg/proc/evalop/evalcompile.go): after compiling the whole expression, the operand stack depth must equal `endDepth` (normally 1 result for an evaluation, per CompileAST/CompileSet); a different depth means the compiled program does not produce the expected number of results. Like the other depth checks, it flags a compiler bug, not user input problems.
Source
Thrown at pkg/proc/evalop/evalcompile.go:288
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"
if ident, ok := f.X.(*ast.Ident); ok && ident.Name == DelvePackage && f.Sel.Name == catch {
if !toplevel {
return fmt.Errorf("%s.%s can only be used at toplevel", DelvePackage, catch)
}
if len(node.Args) != 1 {
return fmt.Errorf("wrong number of arguments for %s.%s", DelvePackage, catch)
}
ctx.pushOp(&DisableErrors{})
return ctx.compileAST(node.Args[0], false)View on GitHub (pinned to a23773e6c3)
Solutions
- Update delve to the latest stable release
- Rewrite the failing expression as simpler separate evaluations
- Report the reproducing expression and error listing to go-delve/delve
Defensive patterns
Strategy: try-catch
Try / catch
if err != nil && strings.Contains(err.Error(), "depth at the end is not") {
// compiler produced unbalanced stack: simplify and retry
return evalSplit(expr)
} Prevention
- Upgrade delve before using advanced expression features
- Prefer several simple print expressions over one large compound expression
- Report reproducing expressions upstream with the embedded Listing
When it happens
Trigger: CompileAST or CompileSet on an expression whose compiled ops leave a different number of values on the stack than required — e.g. an opcode pushes/pops asymmetrically due to a compile bug in an untested expression construct.
Common situations: Appears after delve regressions in the evalop VM, when testing pre-release delve versions, or when expressions combine rare features (casts, delve.catch, call injection) whose opcode emission doesn't balance the stack.
Related errors
- internal debugger error: depth check error at instruction %d
- internal debugger error: depth check error at instruction %d
- internal debugger error: pinning call injection seen before
- hardware breakpoints exhausted
- break on read only not supported
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/3ceca00c5f4272fb.
Report an issue: GitHub.