go-delve/delve · error

cannot rebuild a binary

Error message

cannot rebuild a binary

What it means

Restart-by-rebuild is only possible when Delve launched the target itself and therefore knows the build command. This error is thrown by Restart when the current target was started by attaching to or executing a prebuilt binary (or core) and a restart that requires recompilation is requested. Delve refuses because it cannot know the original build flags and inputs.

Source

Thrown at service/debugger/debugger.go:540

	}
	var grp *proc.TargetGroup
	var err error

	if rebuild {
		switch d.config.ExecuteKind {
		case ExecutingGeneratedFile:
			err = gobuild.GoBuild(d.processArgs[0], d.config.Packages, d.config.BuildFlags)
			if err != nil {
				return nil, fmt.Errorf("could not rebuild process: %s", err)
			}
		case ExecutingGeneratedTest:
			err = gobuild.GoTestBuild(d.processArgs[0], d.config.Packages, d.config.BuildFlags)
			if err != nil {
				return nil, fmt.Errorf("could not rebuild process: %s", err)
			}
		default:
			// We cannot build a process that we didn't start, because we don't know how it was built.
			return nil, errors.New("cannot rebuild a binary")
		}
	}

	if recorded {
		run, stop, err2 := gdbserial.RecordAsync(d.processArgs, d.config.WorkingDir, false, d.config.Stdin, d.config.Stdout, d.config.Stderr)
		if err2 != nil {
			return nil, err2
		}

		d.recordingStart(stop)
		grp, err = d.recordingRun(run)
		d.recordingDone()
	} else {
		grp, err = d.Launch(d.processArgs, d.config.WorkingDir)
	}
	if err != nil {
		return nil, fmt.Errorf("could not launch process: %s", err)
	}

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Relaunch the session with `dlv debug` or `dlv test` so Delve owns the build, then restart works
  2. Rebuild the binary yourself and start a fresh session with `dlv exec <binary>`
  3. Use `restart` only in sessions started in debug/test mode

Example fix

// before
dlv exec ./app   // restart fails: cannot rebuild a binary
// after
dlv debug .      // Delve builds it; `restart` now rebuilds and relaunches
Defensive patterns

Strategy: validation

Validate before calling

func canRestart(cfg *service.Config, startedByDelve bool) error {
    if !startedByDelve && cfg.AttachPid != 0 {
        return errors.New("restart requires a delve-launched session (use dlv debug/dlv test)")
    }
    return nil
}

Type guard

func isRestartable(recording bool, attachPid int, coreFile string) bool {
    return attachPid == 0 && coreFile == ""
}

Try / catch

_, err := dbg.Restart(rebuild, rerun)
if err != nil && err.Error() == "cannot rebuild a binary" {
    // fall back: rebuild externally, then relaunch with dbg.Launch/exec
}

Prevention

When it happens

Trigger: Calling Debugger.Restart (or `dlv restart`) on a session where the target was started via `dlv attach`, `dlv exec`, or a core dump, and the restart path falls through to the default branch that would need to rebuild the executable.

Common situations: Developers attaching to an already-built binary who then try to restart after changing code; CI pipelines restarting exec-mode sessions; using `restart` with `--rerun` style flags against a non-Delve-built binary.

Related errors


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