go-delve/delve · error · ErrNotRecorded

not a recording

Error message

not a recording

What it means

ErrNotRecorded is the sentinel error returned by delve's proc layer when an action that only makes sense on a recorded (traced) program is requested on a live process. Recording-backed operations (reverse stepping, restarts, time travel) require the debugger to have captured execution history, which live backends do not have. The proc layer returns this sentinel so callers can detect the unsupported direction/mode explicitly.

Source

Thrown at pkg/proc/target.go:21

import (
	"errors"
	"fmt"
	"go/constant"
	"os"
	"sort"
	"strings"
	"sync"

	"github.com/go-delve/delve/pkg/dwarf/op"
	"github.com/go-delve/delve/pkg/goversion"
	"github.com/go-delve/delve/pkg/logflags"
	"github.com/go-delve/delve/pkg/proc/internal/ebpf"
)

var (
	// ErrNotRecorded is returned when an action is requested that is
	// only possible on recorded (traced) programs.
	ErrNotRecorded = errors.New("not a recording")

	// ErrNoRuntimeAllG is returned when the runtime.allg list could
	// not be found.
	ErrNoRuntimeAllG = errors.New("could not find goroutine array")

	// ErrProcessDetached indicates that we detached from the target process.
	ErrProcessDetached = errors.New("detached from the process")
)

type LaunchFlags uint8

const (
	LaunchForeground LaunchFlags = 1 << iota
	LaunchDisableASLR
)

// Target represents the process being debugged.
type Target struct {

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Only enable reverse-debugging operations when the session was launched from a recording (dlv replay / rr backend)
  2. Check the backend/recording state before calling ChangeDirection or Restart
  3. Handle the sentinel error by falling back to forward-only execution
  4. Use `so`/forward stepping instead of reverse commands on live targets

Example fix

// before
tgrp.ChangeDirection(proc.Backward) // panics flow with 'not a recording'
// after
if _, err := tgrp.Valid(); err == nil && debuggerIsRecording {
    err = tgrp.ChangeDirection(proc.Backward)
} else {
    return fmt.Errorf("reverse stepping requires a recording (use dlv replay)")
}
Defensive patterns

Strategy: try-catch

Validate before calling

// check session kind before reverse ops
if !isRecordingSession(tgrp) {
    return fmt.Errorf("reverse operations require a recorded target")
}

Type guard

func isRecordingSession(t *proc.TargetGroup) bool {
    _, err := t.Valid()
    return err == nil && t.Selected != nil && t.Selected.Recording() != nil
}

Try / catch

err := tgrp.ChangeDirection(proc.Backward)
if errors.Is(err, proc.ErrNotRecorded) {
    // fall back to forward-only stepping
}

Prevention

When it happens

Trigger: Calling TargetGroup.ChangeDirection (e.g. setting direction to Backward or issuing rev-step/rev-next) or Restart on a process attached via the native or gdbserial (live) backend, since dummyRecordingManipulation.Restart always returns ErrNotRecorded.

Common situations: A user issues 'rewind', 'restart' or reverse-continue in the terminal/DAP client while debugging a normal 'dlv debug'/'dlv attach' session instead of a 'dlv replay' core/trace recording; IDE plugins that expose reverse-debug buttons unconditionally.

Related errors


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