go-delve/delve · error

nothing to stepout to

Error message

nothing to stepout to

What it means

Raised by TargetGroup.StepOut when it cannot determine any destination to step out to: the topmost frame has no return address (topframe.Ret == 0) and no deferred-call breakpoint could be set (deferpc == 0). Delve has nowhere to place the return breakpoint, so stepping out is impossible from this state.

Source

Thrown at pkg/proc/target_exec.go:599

	sameGCond := sameGoroutineCondition(dbp.BinInfo(), selg, curthread.ThreadID())

	if backward {
		if err := stepOutReverse(dbp, topframe, retframe, sameGCond); err != nil {
			return err
		}

		success = true
		return grp.Continue()
	}

	deferpc, err := setDeferBreakpoint(dbp, nil, topframe, sameGCond, false)
	if err != nil {
		return err
	}

	if topframe.Ret == 0 && deferpc == 0 {
		return errors.New("nothing to stepout to")
	}

	if topframe.Ret != 0 {
		topframe, retframe := skipAutogeneratedWrappersOut(grp.Selected, selg, curthread, &topframe, &retframe)
		retFrameCond := astutil.And(sameGCond, frameoffCondition(retframe))
		bp, err := allowDuplicateBreakpoint(dbp.SetBreakpoint(0, retframe.Current.PC, NextBreakpoint, retFrameCond))
		if err != nil {
			return err
		}
		if bp != nil {
			configureReturnBreakpoint(dbp.BinInfo(), bp, topframe, retFrameCond)
		}
	}

	if bp := curthread.Breakpoint(); bp.Breakpoint == nil {
		curthread.SetCurrentBreakpoint(false)
	}

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Continue until the goroutine is in normal user code, then StepOut
  2. Use Next/Step or set an explicit breakpoint at the desired return location instead
  3. Rebuild with optimizations disabled (-gcflags='all=-N -l') for reliable frame info
  4. Check that you're stepping out of the intended goroutine/frame (use stack command)

Example fix

// before
// stopped inside runtime.gopark
err := grp.StepOut() // 'nothing to stepout to'
// after
bp, _ := dbp.SetBreakpoint(0, callerPC, UserBreakpoint, nil)
_ = grp.Continue() // breakpoint at explicit destination instead
Defensive patterns

Strategy: try-catch

Validate before calling

frames, _ := dbp.Stack(0, 20)
top := frames[0]
if top.Ret == 0 && top.Current.File startsWith("runtime/") {
    // stepout not viable; use breakpoint at caller instead
}

Try / catch

if err := grp.StepOut(); err != nil && err.Error() == "nothing to stepout to" {
    // set explicit breakpoint at caller PC and continue instead
}

Prevention

When it happens

Trigger: StepOut called with the goroutine stopped in a frame lacking a resolvable return address (e.g. runtime/bootstrapping frames, frames without proper frame pointer info) and setDeferBreakpoint yields 0 (no deferred call at top frame).

Common situations: Stepping out of runtime functions or deeply optimized frames; stopping at the outermost frame (thread entry) where there is no caller to return to; binaries compiled without frame pointers causing frame recovery failure.

Related errors


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