go-delve/delve · error

invalid memory address or nil pointer dereference [signal SI

Error message

invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation]
Unable to propagate EXC_BAD_ACCESS signal to target process and panic (see https://github.com/go-delve/delve/issues/852)

What it means

BetterBadAccessError is a user-facing message DAP substitutes when the target process dies from EXC_BAD_ACCESS on macOS. Delve cannot re-inject the SIGSEGV so the Go runtime in the debuggee cannot convert it into a panic, so the process is killed and delve reports this augmented string to the IDE so the developer understands the real fault was a nil/invalid pointer dereference in their program.

Source

Thrown at service/dap/server.go:4315

			Seq:  s.getResponseSeq(),
			Type: "response",
		},
		Command:    request.Command,
		RequestSeq: request.Seq,
		Success:    true,
	}
}

func (s *Session) newEvent(event string) *dap.Event {
	return &dap.Event{
		ProtocolMessage: dap.ProtocolMessage{
			Seq:  s.getResponseSeq(),
			Type: "event",
		},
		Event: event,
	}
}

const BetterBadAccessError = `invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation]
Unable to propagate EXC_BAD_ACCESS signal to target process and panic (see https://github.com/go-delve/delve/issues/852)`

const BetterNextWhileNextingError = `Unable to step while the previous step is interrupted by a breakpoint.
Use 'Continue' to resume the original step command.`

func (s *Session) resetHandlesForStoppedEvent() {
	s.stackFrameHandles.reset()
	s.variableHandles.reset()
	s.referencesCollection.reset()
	s.exceptionErr = nil
}

func processExited(state *api.DebuggerState, err error) bool {
	var errProcessExited proc.ErrProcessExited
	isexited := errors.As(err, &errProcessExited)
	return isexited || err == nil && state.Exited
}

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Treat the message as a nil/invalid pointer dereference in your program and inspect the stack frames/variables in the IDE to find the offending dereference.
  2. If the crash only reproduces under the debugger, check delve issue #852 for known macOS signal-propagation limitations and apply any recommended workaround or upgrade delve.
  3. Run the program without the debugger to confirm the panic and get the standard Go stack trace pinpointing the line.
  4. Upgrade delve to the latest version, as signal propagation behavior on macOS improves over releases.

Example fix

// before (debuggee)
u := cfg.Handler.Timeout * time.Second // cfg is nil
// after
if cfg == nil {
    log.Fatal("cfg is nil")
}
u := cfg.Handler.Timeout * time.Second
Defensive patterns

Strategy: try-catch

Validate before calling

// Before running under DAP on macOS, pre-flight the code path that may fault:
if debuggeeVal == nil {
	return fmt.Errorf("refusing to launch: pointer may be nil")
}

Type guard

func isBetterBadAccessError(msg string) bool {
	return strings.Contains(msg, "EXC_BAD_ACCESS") && strings.Contains(msg, "SIGSEGV")
}

Try / catch

resp, err := client.StepIn(ctx, req)
if err != nil && strings.Contains(err.Error(), "EXC_BAD_ACCESS") {
	// process died from a real nil/invalid deref on macOS; signal propagation failed
	log.Printf("target crashed with bad access: %v", err)
	return inspectFramesAndExit()
}

Prevention

When it happens

Trigger: Debugging a Go program on macOS that dereferences a nil pointer or invalid memory address; the runtime attempts to propagate the SIGSEGV as EXC_BAD_ACCESS to the debuggee, fails, and the process dies while under DAP control.

Common situations: Nil map/slice/pointer dereference in a program being debugged in VS Code on macOS; regression where the app crashes only under the debugger; issue go-delve/delve#852 workarounds.

Related errors


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