{"record":{"id":"b52c8db52379d12d","repo":"chenhg5/cc-connect","slug":"googlechat-marshal-attachment-body-w","errorCode":null,"errorMessage":"googlechat: marshal attachment body: %w","messagePattern":"googlechat: marshal attachment body: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"platform/googlechat/googlechat.go","lineNumber":521,"sourceCode":"\tif result.AttachmentDataRef.ResourceName == \"\" {\n\t\treturn \"\", fmt.Errorf(\"googlechat: upload: empty resourceName in response\")\n\t}\n\treturn result.AttachmentDataRef.ResourceName, nil\n}\n\n// buildAttachmentRequest builds the Chat REST API URL and JSON body to post a\n// message that references an already-uploaded attachment (by resource name).\n// Threading behaviour mirrors buildSendRequest.\nfunc buildAttachmentRequest(rc replyContext, resourceName string) (string, []byte, error) {\n\tbody := map[string]any{\n\t\t\"attachment\": []map[string]any{\n\t\t\t{\"attachmentDataRef\": map[string]any{\"resourceName\": resourceName}},\n\t\t},\n\t}\n\tapplyThread(body, rc)\n\tb, err := json.Marshal(body)\n\tif err != nil {\n\t\treturn \"\", nil, fmt.Errorf(\"googlechat: marshal attachment body: %w\", err)\n\t}\n\treturn messageURL(rc), b, nil\n}\n\n// postAttachment uploads data then creates a Chat message carrying the\n// attachmentDataRef. Shared by SendImage and SendFile.\nfunc (p *Platform) postAttachment(ctx context.Context, rc replyContext, filename, mimeType string, data []byte) error {\n\tif rc.space == \"\" {\n\t\treturn fmt.Errorf(\"googlechat: missing space in reply context\")\n\t}\n\tresourceName, err := p.uploadAttachment(ctx, rc.space, filename, mimeType, data)\n\tif err != nil {\n\t\treturn err\n\t}\n\turl, body, err := buildAttachmentRequest(rc, resourceName)\n\tif err != nil {\n\t\treturn err\n\t}","sourceCodeStart":503,"sourceCodeEnd":539,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/googlechat/googlechat.go#L503-L539","documentation":"Returned by buildAttachmentRequest when json.Marshal fails to serialize the Chat message body carrying the attachmentDataRef. The body is built entirely from in-memory maps with an explicit thread key set by applyThread, so marshalling can only fail if a value is unencodable — practically unreachable with stock code, e.g. only if applyThread inserted an unsupported type into the thread field. It is called by postAttachment (SendImage/SendFile) and exercised by TestBuildAttachmentRequest.","triggerScenarios":"Calling SendImage()/SendFile(); json.Marshal(body) returns an error — only possible if the body map contains a value json.Marshal cannot encode (e.g. a channel/func introduced via a modified applyThread).","commonSituations":"Effectively never hit in production with stock code; would indicate a regression where thread or other fields carry non-JSON-serializable values.","solutions":["Confirm unmodified library code; the body consists only of strings, maps, and slices.","If applyThread was changed, ensure it only sets JSON-encodable values (strings/maps).","Report a bug with the wrapped cause if reproducible on stock code."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := p.SendImage(ctx, target, path); err != nil {\n    if strings.Contains(err.Error(), \"marshal attachment body\") {\n        return fmt.Errorf(\"googlechat body marshal failure (library bug): %w\", err)\n    }\n    return err\n}","preventionTips":["Keep applyThread and body construction stock — only JSON-encodable values belong in the body map.","Report occurrences upstream as bugs.","Pin library versions to avoid local modifications introducing unencodable values."],"tags":["googlechat","json","unreachable"],"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"}