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

  1. Report to go-delve/delve with the exact expression/condition — this is a debugger internal invariant violation.
  2. Rewrite the expression in a simpler equivalent form (fewer nested operators, explicit parentheses, intermediate steps via separate evaluations).
  3. Split compound expressions: evaluate sub-expressions individually instead of one large expression.
  4. 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

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


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