{"record":{"id":"4375e17941b097b8","repo":"go-delve/delve","slug":"can-not-watch-q","errorCode":null,"errorMessage":"can not watch %q","messagePattern":"can not watch %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/proc/breakpoints.go","lineNumber":734,"sourceCode":"}\n\n// SetWatchpoint sets a data breakpoint at addr and stores it in the\n// process wide break point table.\nfunc (t *Target) SetWatchpoint(logicalID int, scope *EvalScope, expr string, wtype WatchType, cond ast.Expr) (*Breakpoint, error) {\n\tif (wtype&WatchWrite == 0) && (wtype&WatchRead == 0) {\n\t\treturn nil, errors.New(\"at least one of read and write must be set for watchpoint\")\n\t}\n\n\tn, err := parser.ParseExpr(expr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\txv, err := scope.evalAST(n)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif xv.Addr == 0 || xv.Flags&VariableFakeAddress != 0 || xv.DwarfType == nil {\n\t\treturn nil, fmt.Errorf(\"can not watch %q\", expr)\n\t}\n\tif xv.Unreadable != nil {\n\t\treturn nil, fmt.Errorf(\"expression %q is unreadable: %v\", expr, xv.Unreadable)\n\t}\n\tif xv.Kind == reflect.UnsafePointer || xv.Kind == reflect.Invalid {\n\t\treturn nil, fmt.Errorf(\"can not watch variable of type %s\", xv.Kind.String())\n\t}\n\n\t// Special handling for interface types\n\tif xv.Kind == reflect.Interface {\n\t\t// For interfaces, we want to watch the data they point to\n\t\t// Read the interface to get the data pointer\n\t\t_, data, _ := xv.readInterface()\n\t\tif xv.Unreadable != nil {\n\t\t\treturn nil, fmt.Errorf(\"error reading interface %q: %v\", expr, xv.Unreadable)\n\t\t}\n\t\tif data == nil {\n\t\t\treturn nil, fmt.Errorf(\"invalid interface %q\", expr)","sourceCodeStart":716,"sourceCodeEnd":752,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/breakpoints.go#L716-L752","documentation":"SetWatchpoint evaluates the given expression as an AST to find the watched variable's address. If the result has no address (Addr==0), a fake address, or no DWARF type, Delve cannot install a hardware watchpoint on it, so it returns this error naming the expression.","triggerScenarios":"Calling SetWatchpoint with an expression that does not resolve to a concrete memory-resident variable: literals, register-allocated temporaries, composite expressions, package constants, or variables whose type info is missing.","commonSituations":"Watching an optimized-out local (kept in registers only, no stack address); watching 'x.y.z' where the intermediate was folded by the compiler; watching a constant or function return value instead of an addressable variable; missing DWARF type info due to stripped binary.","solutions":["Watch an addressable variable stored in memory; take its address first if needed (e.g. watch *&x)","Rebuild with -gcflags='all=-N -l' so locals are not optimized into registers and keep a stack address","Ensure the binary retains DWARF debug info (no -w, not stripped)","Restructure code to store the value of interest in a variable before watching it"],"exampleFix":"// before\ndlv: watch someFunc()\n// after\nval := someFunc()\nwatch val  // val is now an addressable memory variable","handlingStrategy":"validation","validationCode":"xv, err := scope.EvalExpression(expr, LoadConfig{})\nwatchable := err == nil && xv.Addr != 0 && xv.DwarfType != nil && xv.Flags&proc.VariableFakeAddress == 0","typeGuard":"func watchable(v *proc.Variable) bool { return v != nil && v.Addr != 0 && v.DwarfType != nil && v.Flags&proc.VariableFakeAddress == 0 }","tryCatchPattern":"bp, err := db.SetWatchpoint(0, 0, expr, Read, []string{})\nif err != nil && strings.HasPrefix(err.Error(), \"can not watch\") {\n    return fmt.Errorf(\"expression %q is not an addressable variable; assign it to a local first\", expr)\n}","preventionTips":["Only watch local or heap variables that live at a memory address","Rebuild with -gcflags='all=-N -l' to prevent register-allocation hiding variables","Never watch literals, constants, or function call results directly","Ensure the binary keeps DWARF type info (avoid -w/strip)"],"tags":["debugger","watchpoints","go","variables"],"backgroundTag":"watchpoint-not-addressable","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}