{"record":{"id":"3ad632519fed71e3","repo":"chenhg5/cc-connect","slug":"marshal-w-3ad632","errorCode":null,"errorMessage":"marshal: %w","messagePattern":"marshal: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/copilot/jsonrpc.go","lineNumber":61,"sourceCode":"\nfunc (e *jsonRPCError) Error() string {\n\treturn fmt.Sprintf(\"JSON-RPC error %d: %s\", e.Code, e.Message)\n}\n\n// lspWriter writes Content-Length framed JSON-RPC messages.\ntype lspWriter struct {\n\tw  io.Writer\n\tmu sync.Mutex\n}\n\nfunc newLSPWriter(w io.Writer) *lspWriter {\n\treturn &lspWriter{w: w}\n}\n\nfunc (lw *lspWriter) writeMessage(v any) error {\n\tdata, err := json.Marshal(v)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"marshal: %w\", err)\n\t}\n\n\theader := fmt.Sprintf(\"Content-Length: %d\\r\\n\\r\\n\", len(data))\n\n\tlw.mu.Lock()\n\tdefer lw.mu.Unlock()\n\n\tif _, err := io.WriteString(lw.w, header); err != nil {\n\t\treturn fmt.Errorf(\"write header: %w\", err)\n\t}\n\tif _, err := lw.w.Write(data); err != nil {\n\t\treturn fmt.Errorf(\"write body: %w\", err)\n\t}\n\treturn nil\n}\n\n// lspReader reads Content-Length framed JSON-RPC messages.\ntype lspReader struct {","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/agent/copilot/jsonrpc.go#L43-L79","documentation":"The lspWriter failed to JSON-marshal a JSON-RPC message (request, notification, response, or error) before framing it with Content-Length. json.Marshal fails only for unsupported types (channels, funcs, cyclic structures), so this indicates a bug in message construction rather than environment issues.","triggerScenarios":"call/notify/respond/writeResponse/writeError passing a params or result value containing a non-marshalable type (chan, func, or a reference cycle) to writeMessage.","commonSituations":"After a code change introducing a custom params type with unsupported fields (e.g. sync.Mutex captured by value, func field, cyclic pointer graph).","solutions":["Inspect the value being marshaled in the failing call and remove/replace non-marshalable fields","Add json:\"-\" tags to fields that must not be serialized","Convert custom types to plain serializable structs/maps before calling call/notify","Add a unit test marshaling every JSON-RPC message type the agent sends"],"exampleFix":"// before\ntype deleteParams struct {\n    SessionID string `json:\"sessionId\"`\n    onClose func() // not marshalable\n}\n// after\ntype deleteParams struct {\n    SessionID string `json:\"sessionId\"`\n    onClose func() `json:\"-\"`\n}","handlingStrategy":"validation","validationCode":"// guard helper for JSON-RPC payloads\nfunc mustMarshalable(v any) error {\n    var b bytes.Buffer\n    enc := json.NewEncoder(&b)\n    if err := enc.Encode(v); err != nil { return fmt.Errorf(\"unmarshalable rpc payload: %w\", err) }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := rpc.call(ctx, method, params); err != nil && strings.Contains(err.Error(), \"marshal:\") {\n    slog.Error(\"non-serializable RPC payload — bug in params construction\", \"method\", method, \"err\", err)\n}","preventionTips":["Keep JSON-RPC params structs free of funcs/chans/mutexes; tag internal fields json:\"-\"","Add round-trip tests marshaling every outbound request type","Use plain maps/DTOs at the RPC boundary"],"tags":["go","json","jsonrpc","serialization"],"backgroundTag":"json-marshal-failed","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}