chenhg5/cc-connect · info
googlechat: marshal attachment body: %w
Error message
googlechat: marshal attachment body: %w
What it means
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.
Source
Thrown at platform/googlechat/googlechat.go:521
if result.AttachmentDataRef.ResourceName == "" {
return "", fmt.Errorf("googlechat: upload: empty resourceName in response")
}
return result.AttachmentDataRef.ResourceName, nil
}
// buildAttachmentRequest builds the Chat REST API URL and JSON body to post a
// message that references an already-uploaded attachment (by resource name).
// Threading behaviour mirrors buildSendRequest.
func buildAttachmentRequest(rc replyContext, resourceName string) (string, []byte, error) {
body := map[string]any{
"attachment": []map[string]any{
{"attachmentDataRef": map[string]any{"resourceName": resourceName}},
},
}
applyThread(body, rc)
b, err := json.Marshal(body)
if err != nil {
return "", nil, fmt.Errorf("googlechat: marshal attachment body: %w", err)
}
return messageURL(rc), b, nil
}
// postAttachment uploads data then creates a Chat message carrying the
// attachmentDataRef. Shared by SendImage and SendFile.
func (p *Platform) postAttachment(ctx context.Context, rc replyContext, filename, mimeType string, data []byte) error {
if rc.space == "" {
return fmt.Errorf("googlechat: missing space in reply context")
}
resourceName, err := p.uploadAttachment(ctx, rc.space, filename, mimeType, data)
if err != nil {
return err
}
url, body, err := buildAttachmentRequest(rc, resourceName)
if err != nil {
return err
}View on GitHub (pinned to 4000b2338a)
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.
Defensive patterns
Strategy: try-catch
Try / catch
if err := p.SendImage(ctx, target, path); err != nil {
if strings.Contains(err.Error(), "marshal attachment body") {
return fmt.Errorf("googlechat body marshal failure (library bug): %w", err)
}
return err
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: Effectively never hit in production with stock code; would indicate a regression where thread or other fields carry non-JSON-serializable values.
Understand the failure class
Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.
Related errors
- googlechat: marshal body: %w
- googlechat: upload: create metadata part: %w
- googlechat: upload: encode metadata: %w
- googlechat: upload: write media: %w
- googlechat: upload: finalize multipart body: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/b52c8db52379d12d.
Report an issue: GitHub.