go-delve/delve · error

breakpoint name already exists

Error message

breakpoint name already exists

What it means

Breakpoint names must be unique within a debugging session. CreateBreakpoint checks via findBreakpointByName and rejects any request whose Name is already used by an existing breakpoint. This prevents ambiguity when referencing breakpoints by name (e.g. in conditions, locations, or RPC calls).

Source

Thrown at service/debugger/debugger.go:706

//
// If LocExpr is specified it will be used, along with substitutePathRules,
// to re-enable the breakpoint after it is disabled.
//
// If suspended is true a logical breakpoint will be created even if the
// location can not be found, the backend will attempt to enable the
// breakpoint every time a new plugin is loaded.
func (d *Debugger) CreateBreakpoint(requestedBp *api.Breakpoint, locExpr string, substitutePathRules [][2]string, suspended bool) (*api.Breakpoint, error) {
	d.targetMutex.Lock()
	defer d.targetMutex.Unlock()

	var (
		setbp proc.SetBreakpoint
		err   error
	)

	if requestedBp.Name != "" {
		if d.findBreakpointByName(requestedBp.Name) != nil {
			return nil, errors.New("breakpoint name already exists")
		}
	}

	if lbp := d.target.LogicalBreakpoints[requestedBp.ID]; lbp != nil {
		abp := d.convertBreakpoint(lbp)
		return abp, proc.BreakpointExistsError{File: lbp.File, Line: lbp.Line}
	}

	switch {
	case requestedBp.TraceReturn:
		if len(d.target.Targets()) != 1 {
			return nil, ErrNotImplementedWithMultitarget
		}
		setbp.PidAddrs = []proc.PidAddr{{Pid: d.target.Selected.Pid(), Addr: requestedBp.Addr}}
	case len(requestedBp.File) > 0:
		fileName := requestedBp.File
		if runtime.GOOS == "windows" {
			// Accept fileName which is case-insensitive and slash-insensitive match

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Choose a different, unique name for the new breakpoint
  2. Amend the existing breakpoint instead of creating a new one (AmendBreakpoint)
  3. Clear the existing breakpoint first (ClearBreakpoint by ID) then recreate it with the desired name
  4. Look up the existing breakpoint with ListBreakpoints/findBreakpointByName and reuse its ID

Example fix

// before
bp := &api.Breakpoint{File: "main.go", Line: 10, Name: "entry"}
d.CreateBreakpoint(bp) // second call fails: name already exists
// after
if d.findBreakpointByName("entry") == nil {
    d.CreateBreakpoint(bp)
} else {
    amend := &api.Breakpoint{ID: existing.ID, Name: "entry", File: "main.go", Line: 10}
    d.AmendBreakpoint(amend)
}
Defensive patterns

Strategy: validation

Validate before calling

if bp.Name != "" && dbg.findBreakpointByName(bp.Name) != nil {
    return fmt.Errorf("name %q in use; pick another or amend ID", bp.Name)
}

Type guard

func nameIsFree(dbg *debugger.Debugger, name string) bool {
    return name == "" || dbg == nil // check via ListBreakpoints in client code
}

Try / catch

_, err := dbg.CreateBreakpoint(bp)
if err != nil && strings.Contains(err.Error(), "breakpoint name already exists") {
    // reuse existing ID via AmendBreakpoint or choose a new name
}

Prevention

When it happens

Trigger: Calling Debugger.CreateBreakpoint (RPC2 service/createBreakpoint, DAP setBreakpoints with names, or `break -name X` twice) with a non-empty requestedBp.Name that an existing logical breakpoint already holds.

Common situations: Re-running a script/IDE configuration that sets named breakpoints without clearing old ones; reusing a conventional name like "main-entry" across sessions; tools that retry breakpoint creation after a partial failure.

Related errors


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