go-delve/delve · error

no breakpoint at address %#x

Error message

no breakpoint at address %#x

What it means

ClearBreakpoint normally works by breakpoint ID, but legacy clients pass a breakpoint with only an address (ID == 0). In that case delve looks up a physical breakpoint at that address in the selected target. If no breakpoint is set at that exact address, it returns "no breakpoint at address %#x". It also fails with ErrNotImplementedWithMultitarget when multiple targets exist.

Source

Thrown at service/debugger/debugger.go:938

	lbp.CustomCommands = requested.CustomCommands
	lbp.UserData = requested.UserData
	lbp.RootFuncName = requested.RootFuncName
	lbp.TraceFollowCalls = requested.TraceFollowCalls

	return d.target.ChangeBreakpointCondition(lbp, requested.Cond, requested.HitCond, requested.HitCondPerG)
}

// ClearBreakpoint clears a breakpoint.
func (d *Debugger) ClearBreakpoint(requestedBp *api.Breakpoint) (*api.Breakpoint, error) {
	d.targetMutex.Lock()
	defer d.targetMutex.Unlock()
	if requestedBp.ID == 0 {
		if len(d.target.Targets()) != 1 {
			return nil, ErrNotImplementedWithMultitarget
		}
		bp := d.target.Selected.Breakpoints().M[requestedBp.Addr]
		if bp == nil {
			return nil, fmt.Errorf("no breakpoint at address %#x", requestedBp.Addr)
		}
		requestedBp.ID = bp.LogicalID()
	}

	lbp := d.target.LogicalBreakpoints[requestedBp.ID]
	if lbp == nil {
		return nil, fmt.Errorf("no breakpoint with ID %d", requestedBp.ID)
	}
	clearedBp := d.convertBreakpoint(lbp)

	err := d.target.SetBreakpointEnabled(lbp, false)
	if err != nil {
		return nil, err
	}

	delete(d.target.LogicalBreakpoints, requestedBp.ID)

	d.log.Infof("cleared breakpoint: %#v", clearedBp)

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Use the breakpoint's numeric ID instead of the address (clear by ID).
  2. Re-read the breakpoint list to get the current address/ID before clearing.
  3. Avoid clearing by address in multi-process (follow-exec) sessions; it is not implemented there.
  4. Check the address matches exactly the breakpoint's Addr from ListBreakpoints (function entry offsets matter).

Example fix

// before
bp, err := d.ClearBreakpoint(&api.Breakpoint{Addr: 0x401000})
// after
bps, _ := d.ListBreakpoints(false)
bp, err := d.ClearBreakpoint(&api.Breakpoint{ID: bps[0].ID})
Defensive patterns

Strategy: validation

Validate before calling

bps, _ := d.ListBreakpoints(false)
found := false
for _, bp := range bps {
    if bp.Addr == addr {
        found = true
        break
    }
}
if !found {
    return fmt.Errorf("no breakpoint at %#x; nothing to clear", addr)
}

Try / catch

_, err := d.ClearBreakpoint(&api.Breakpoint{Addr: addr})
if err != nil && strings.Contains(err.Error(), "no breakpoint at address") {
    // already cleared or stale address; resync
    bps, _ := d.ListBreakpoints(false)
    _ = bps
}

Prevention

When it happens

Trigger: ClearBreakpoint called with api.Breakpoint{Addr: X} (ID 0) where no breakpoint exists at X; address computed from a stale binary layout; calling after the breakpoint was already cleared; multitarget session with ID-less clear request.

Common situations: Older clients or scripts that clear by address; binary rebuilt between setting and clearing so addresses shifted; double-clear after an error; specifying a line whose resolved address never had a breakpoint.

Related errors


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