{"record":{"id":"0cd7d58d49860ff2","repo":"chenhg5/cc-connect","slug":"googlechat-upload-empty-resourcename-in-response","errorCode":null,"errorMessage":"googlechat: upload: empty resourceName in response","messagePattern":"googlechat: upload: empty resourceName in response","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/googlechat/googlechat.go","lineNumber":504,"sourceCode":"\t\treturn \"\", err\n\t}\n\tdefer func() {\n\t\tif err := resp.Body.Close(); err != nil {\n\t\t\tslog.Warn(\"googlechat: close upload response body\", \"error\", err)\n\t\t}\n\t}()\n\n\tvar result struct {\n\t\tAttachmentDataRef struct {\n\t\t\tResourceName string `json:\"resourceName\"`\n\t\t} `json:\"attachmentDataRef\"`\n\t}\n\tdefer func() { _, _ = io.Copy(io.Discard, resp.Body) }()\n\tif err := json.NewDecoder(resp.Body).Decode(&result); err != nil {\n\t\treturn \"\", fmt.Errorf(\"googlechat: upload: decode response: %w\", err)\n\t}\n\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}","sourceCodeStart":486,"sourceCodeEnd":522,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/googlechat/googlechat.go#L486-L522","documentation":"Returned by uploadAttachment when the Chat upload response decodes successfully but attachmentDataRef.resourceName is empty — the server acknowledged the upload but did not return the attachment reference needed to send the message. This indicates an unexpected/empty API response for the upload. It surfaces via postAttachment from SendImage/SendFile.","triggerScenarios":"Calling SendImage()/SendFile(); the upload endpoint responds with JSON lacking attachmentDataRef.resourceName — e.g. the API changed its response shape or an edge response omitted the ref.","commonSituations":"Google Chat API behavior changes; uploading with a scope the API accepts only partially (auth issues); zero-byte or unusual payloads causing the server to skip the attachment ref.","solutions":["Log the full decoded response to see what fields the server actually returned.","Verify the OAuth scopes cover media upload with send permission.","Retry the upload — transient server-side issues can yield empty refs.","Check the Google Workspace API release notes / issue tracker for Chat upload response schema changes and update the library."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// avoid zero-byte uploads which can produce empty refs\nfi, err := os.Stat(path)\nif err != nil || fi.Size() == 0 {\n    return fmt.Errorf(\"refusing to upload empty or missing file %q\", path)\n}","typeGuard":null,"tryCatchPattern":"name, err := p.SendFile(ctx, target, path)\nif err != nil && strings.Contains(err.Error(), \"empty resourceName\") {\n    time.Sleep(2 * time.Second)\n    return p.SendFile(ctx, target, path)\n}","preventionTips":["Never upload zero-byte files.","Retry transient upload failures with backoff.","Track Google Workspace release notes for Chat upload API changes.","Log the full upload response when this error occurs to aid upstream bug reports."],"tags":["googlechat","upload","api-response","empty-field"],"backgroundTag":"empty-api-response","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}