go-delve/delve · error
internal debugger error: wrong stack size at end %d
Error message
internal debugger error: wrong stack size at end %d
What it means
result() unwinds the evalStack after running an evalop program: a well-formed program leaves exactly 0 values (statements) or 1 value (expressions). Any other remaining depth means the compiled op program and the stack machine disagree — an internal invariant violation. The error is attached to the stack instead of returned directly so cleanup paths still run.
Source
Thrown at pkg/proc/eval.go:1088
}
stack.lastRetiredFncall = fncall
// Resume target to undo one call
stack.callInjectionContinue = true
scope.callCtx.injectionThread = nil
return
}
}
func (stack *evalStack) result(cfg *LoadConfig) (*Variable, error) {
var r *Variable
switch len(stack.stack) {
case 0:
// ok
case 1:
r = stack.peek()
default:
if stack.err == nil {
stack.err = fmt.Errorf("internal debugger error: wrong stack size at end %d", len(stack.stack))
}
}
if r != nil && cfg != nil && stack.err == nil {
r.loadValue(*cfg)
}
return r, stack.err
}
// executeOp executes the opcode at stack.ops[stack.opidx] and increments stack.opidx.
func (stack *evalStack) executeOp() {
scope, ops, curthread := stack.scope, stack.ops, stack.curthread
defer func() {
err := recover()
if err != nil {
logflags.Bug.Inc()
stack.err = fmt.Errorf("internal debugger error: %v (recovered)\n%s", err, string(debug.Stack()))
}
}()View on GitHub (pinned to a23773e6c3)
Solutions
- Report to go-delve/delve with the exact expression/condition — this is a debugger internal invariant violation.
- Rewrite the expression in a simpler equivalent form (fewer nested operators, explicit parentheses, intermediate steps via separate evaluations).
- Split compound expressions: evaluate sub-expressions individually instead of one large expression.
- Test with a stock dlv CLI on the same expression to confirm it's not a client-side query construction bug.
Defensive patterns
Strategy: try-catch
Validate before calling
// sanity-check expression shape client-side before submitting
if strings.Count(expr, "(") != strings.Count(expr, ")") {
return errors.New("unbalanced parentheses in expression")
} Try / catch
r, err := scope.EvalExpression(expr, cfg)
if err != nil && strings.Contains(err.Error(), "wrong stack size at end") {
// retry with a simplified form of the expression
r, err = scope.EvalExpression(simplify(expr), cfg)
} Prevention
- Keep breakpoint conditions and scripted expressions simple; split complex ones into steps
- Test expressions against stock dlv CLI before embedding in tooling
- Update Delve when upgrading the Go toolchain (evalop changes track compiler behavior)
- Report any expression that reproduces this to go-delve/delve — it is an internal invariant bug
When it happens
Trigger: EvalExpression, SetVariable, evalAST, evalBreakpointCondition, or finishEvalExpressionWithCalls finishing with the eval stack holding 2+ values — caused by an op sequence pushing more values than it pops, typically due to a compiler/evaluator mismatch in evalop for the given expression shape, or a corrupted/ill-formed expression program.
Common situations: Evaluating complex nested expressions that expose an evalop compilation bug; breakpoint conditions compiled differently between versions; custom clients sending unusual expression syntax through the RPC eval APIs; regression after a Delve or Go toolchain upgrade.
Related errors
- internal debugger error: eval program finished without error
- internal debugger error: could not undo injected call during
- unexpected return type for mallocgc call: %v
- could not decode first frame
- unable to find function context
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/adb5821ae48ea90f.
Report an issue: GitHub.