{"record":{"id":"06561acee72d6751","repo":"wavetermdev/waveterm","slug":"failed-to-decode-base64-data-w","errorCode":null,"errorMessage":"failed to decode base64 data: %w","messagePattern":"failed to decode base64 data: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/aiusechat/anthropic/anthropic-convertmessage.go","lineNumber":437,"sourceCode":"\t\t\t\tSource: &anthropicSource{\n\t\t\t\t\tType: \"url\",\n\t\t\t\t\tURL:  p.URL,\n\t\t\t\t},\n\t\t\t}, nil\n\t\t}\n\n\tcase p.MediaType == \"text/plain\":\n\t\t// text/plain → Anthropic document block, but NO URL form supported\n\t\tif strings.HasPrefix(p.URL, \"data:\") {\n\t\t\t// Data URL → decode base64 data and return as document with PlainTextSource\n\t\t\tparts := strings.SplitN(p.URL, \",\", 2)\n\t\t\tif len(parts) != 2 {\n\t\t\t\treturn nil, errors.New(\"invalid data URL format\")\n\t\t\t}\n\t\t\t// Decode base64 data\n\t\t\ttextData, err := base64.StdEncoding.DecodeString(parts[1])\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to decode base64 data: %w\", err)\n\t\t\t}\n\t\t\treturn &anthropicMessageContentBlock{\n\t\t\t\tType: \"document\",\n\t\t\t\tSource: &anthropicSource{\n\t\t\t\t\tType:      \"text\",\n\t\t\t\t\tData:      string(textData),\n\t\t\t\t\tMediaType: \"text/plain\",\n\t\t\t\t},\n\t\t\t}, nil\n\t\t} else {\n\t\t\t// HTTP/HTTPS URL → not supported inline, would need to fetch\n\t\t\treturn nil, fmt.Errorf(\"dropping text/plain file with URL (must be fetched and converted to base64 or uploaded to Files API)\")\n\t\t}\n\n\tdefault:\n\t\t// Other media types → not supported inline, must upload and use file_id\n\t\treturn nil, fmt.Errorf(\"dropping file with unsupported media type '%s' (must be uploaded to Files API and sent as file_id)\", p.MediaType)\n\t}","sourceCodeStart":419,"sourceCodeEnd":455,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/aiusechat/anthropic/anthropic-convertmessage.go#L419-L455","documentation":"When a text/plain file part arrives as a data: URL, the converter base64-decodes the payload to build an Anthropic plain-text document source. This error wraps the base64.StdEncoding.DecodeString failure, meaning the payload after the comma is not valid standard base64 (bad characters, wrong padding, URL-safe alphabet, or percent-encoded/URL-encoded content).","triggerScenarios":"Sending a text/plain part whose data: URL payload was produced with base64.URL_ENCODING, is truncated, contains whitespace/newlines, or is actually URL-encoded plain text rather than base64.","commonSituations":"Frontends encoding text with encodeURIComponent instead of btoa; double-encoding when the data URL was itself JSON-escaped; copying a data URL and dropping characters; mixing URL-safe and standard base64.","solutions":["Regenerate the data URL with standard base64 (btoa in JS, base64.StdEncoding in Go)","Strip whitespace/newlines from the base64 payload before sending","If the payload is URL-safe base64, convert it to standard base64 (replace - and _ with + and /, pad with =)","Verify the data URL format is data:text/plain;base64,<payload> with the ;base64 marker handled upstream"],"exampleFix":"// before\nurl := \"data:text/plain;base64,\" + urlSafeBase64(text) // URL-safe alphabet, padding issues\n// after\nurl := \"data:text/plain;base64,\" + base64.StdEncoding.EncodeToString([]byte(text))","handlingStrategy":"validation","validationCode":"func validStdBase64(s string) bool {\n    _, err := base64.StdEncoding.DecodeString(s)\n    return err == nil\n}\n// extract payload from data URL, then: if !validStdBase64(payload) { normalize or reject }","typeGuard":"func isStdBase64(s string) bool {\n    _, err := base64.StdEncoding.DecodeString(s)\n    return err == nil\n}","tryCatchPattern":"if _, err := convert(msg); err != nil {\n    if strings.Contains(err.Error(), \"failed to decode base64\") {\n        normalized := strings.NewReplacer(\"-\", \"+\", \"_\", \"/\", \"\\n\", \"\", \"\\r\", \"\", \" \", \"\").Replace(payload)\n        return convert(rebuildDataURL(normalized))\n    }\n    return err\n}","preventionTips":["Always encode with standard base64 (base64.StdEncoding / btoa), not URL-safe variants","Strip whitespace and newlines from base64 payloads","Never percent-encode data URL payloads intended as base64"],"tags":["go","base64","encoding","data-url","anthropic"],"backgroundTag":"invalid-base64-data","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}