go-delve/delve · error
can not disable watchpoints
Error message
can not disable watchpoints
What it means
Watchpoints (data breakpoints on memory addresses/variables) cannot be toggled into the disabled state in Delve; they can only be created or removed. amendBreakpoint rejects any amend request that sets Disabled=true on a logical breakpoint that is a watchpoint.
Source
Thrown at service/debugger/debugger.go:868
d.targetMutex.Lock()
defer d.targetMutex.Unlock()
if len(d.target.Targets()) != 1 {
return ErrNotImplementedWithMultitarget
}
p := d.target.Selected
return p.SetEBPFTracepoint(fnName)
}
// amendBreakpoint will update the breakpoint with the matching ID.
// It also enables or disables the breakpoint.
// We can consume this function to avoid locking a goroutine.
func (d *Debugger) amendBreakpoint(amend *api.Breakpoint) error {
original := d.target.LogicalBreakpoints[amend.ID]
if original == nil {
return fmt.Errorf("no breakpoint with ID %d", amend.ID)
}
if d.isWatchpoint(original) && amend.Disabled {
return errors.New("can not disable watchpoints")
}
err := d.copyLogicalBreakpointInfo(original, amend)
if err != nil {
return err
}
err = d.target.SetBreakpointEnabled(original, !amend.Disabled)
if err != nil {
return err
}
return nil
}
func (d *Debugger) isWatchpoint(lbp *proc.LogicalBreakpoint) bool {
t := proc.ValidTargets{Group: d.target}
for t.Next() {
for _, bp := range t.Breakpoints().M {
if bp.LogicalID() == lbp.LogicalID {View on GitHub (pinned to a23773e6c3)
Solutions
- Clear the watchpoint instead of disabling it (ClearBreakpoint with its ID)
- Filter watchpoints out before sending batch disable operations from your frontend
- Re-create the watchpoint later when you want it inactive temporarily
Example fix
// before
amend := &api.Breakpoint{ID: watchpointID, Disabled: true}
d.AmendBreakpoint(amend) // error
// after
d.ClearBreakpoint(watchpointID) // remove; recreate when needed Defensive patterns
Strategy: validation
Validate before calling
for _, bp := range toDisable {
if isWatchpoint(bp) { // e.g. identified via WatchExpr != "" or Addr != 0 && Line == 0
clearIDs = append(clearIDs, bp.ID)
} else {
amendIDs = append(amendIDs, bp.ID)
}
} Type guard
func isWatchpointBP(bp *api.Breakpoint) bool {
return bp.WatchExpr != "" || bp.Addr != 0 && bp.Line == 0
} Try / catch
err := dbg.AmendBreakpoint(&api.Breakpoint{ID: id, Disabled: true})
if err != nil && strings.Contains(err.Error(), "can not disable watchpoints") {
dbg.ClearBreakpoint(id) // remove instead of disable
} Prevention
- In batch-disable UI logic, route watchpoints to ClearBreakpoint instead
- Detect watchpoints via their WatchExpr/addr fields before toggling enabled state
- Inform users that watchpoints support delete, not pause
When it happens
Trigger: Calling Debugger.AmendBreakpoint (RPC2 service/amendBreakpoint, DAP update of breakpoints, or terminal `toggle` on a watchpoint) with amend.Disabled == true where d.isWatchpoint(original) is true.
Common situations: IDEs that blanket-apply `disabled: true` to all breakpoints when the user disables a group; scripting tools toggling watchpoints like normal line breakpoints; stale UI state re-sending watchpoint configs after the watchpoint was conceptually removed.
Related errors
- breakpoint exception
- too many arguments to trace
- wrong number of arguments: watch [-r|-w|-rw] <expr>
- filter not supported on breakpoint
- breakpoint name can not be a number
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/8ed6d3343a91de55.
Report an issue: GitHub.