go-delve/delve · error
malformed data ID: %q
Error message
malformed data ID: %q
What it means
A DAP data breakpoint's DataId must be the string '<goid>,<frame>,<expression>' (three comma-separated parts). The submitted DataId did not have exactly three comma-separated components, so Delve cannot decode it.
Source
Thrown at service/dap/server.go:1990
})
}
const dataBpPrefix = "dataBreakpoint"
func (s *Session) onSetDataBreakpointRequest(request *dap.SetDataBreakpointsRequest) {
breakpoints := s.setBreakpoints(s.getWatchpoints(), len(request.Arguments.Breakpoints), func(i int) *bpMetadata {
want := request.Arguments.Breakpoints[i]
return &bpMetadata{
name: fmt.Sprintf("%s %s", dataBpPrefix, want.DataId),
condition: want.Condition,
hitCondition: want.HitCondition,
logMessage: "",
}
}, func(i int) (*bpLocation, error) {
want := request.Arguments.Breakpoints[i]
v := strings.SplitN(want.DataId, ",", 3)
if len(v) != 3 {
return nil, fmt.Errorf("malformed data ID: %q", want.DataId)
}
goid, err1 := strconv.ParseInt(v[0], 0, 64)
frame, err2 := strconv.ParseInt(v[1], 0, 64)
if err1 != nil || err2 != nil {
return nil, fmt.Errorf("malformed data ID: %q", want.DataId)
}
var wtype api.WatchType
switch want.AccessType {
case "read":
wtype = api.WatchRead
case "write":
wtype = api.WatchWrite
case "readWrite":
wtype = api.WatchRead | api.WatchWrite
default:
return nil, fmt.Errorf("unknown access type: %q", want.AccessType)
}
return &bpLocation{View on GitHub (pinned to a23773e6c3)
Solutions
- Use the dataId string exactly as returned in Variable results from a previous variables request
- Re-fetch scopes/variables after a restart and re-create data breakpoints from fresh IDs
- Ensure no commas inside the expression part break the 3-part format
Example fix
// before
{"breakpoints":[{"dataId":"42"}]}
// after: goid,frame,expr as returned by DAP variables
{"breakpoints":[{"dataId":"1,0,myVar","accessType":"write"}]} Defensive patterns
Strategy: type-guard
Validate before calling
func validDataId(id string) bool { parts := strings.Split(id, ","); return len(parts) == 3 } Type guard
func isWellFormDataId(id string) bool {
v := strings.Split(id, ",")
if len(v) != 3 { return false }
_, e1 := strconv.ParseInt(v[0], 0, 64)
_, e2 := strconv.ParseInt(v[1], 0, 64)
return e1 == nil && e2 == nil
} Try / catch
if err := setDataBreakpoints(req); err != nil { if strings.Contains(err.Error(), "malformed data ID") { req.Breakpoints = refreshDataIdsFromVariables(); retry } } Prevention
- Always echo dataId strings verbatim from Variable responses
- Refresh data breakpoints from a new variables request after restarts
- Never construct dataIds by hand
When it happens
Trigger: setDataBreakpoints request whose Arguments.Breakpoints[i].DataId is not produced by a previous scopes/variables call (i.e. not of the form 'goid,frame,expr').
Common situations: A client fabricating data breakpoint IDs instead of echoing back the dataId provided in Variable responses, or IDs from an older session/target after restart.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- unknown access type: %q
- breakpoint name %q could not be parsed as a function. name m
- break on read only not supported
- hardware breakpoints not supported
- hardware breakpoints exhausted
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/6bea079569518461.
Report an issue: GitHub.