{"record":{"id":"d68851c97714f4f1","repo":"larksuite/cli","slug":"draft-raw-eml-is-not-valid-base64url","errorCode":null,"errorMessage":"draft raw EML is not valid base64url","messagePattern":"draft raw EML is not valid base64url","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shortcuts/mail/draft/parse.go","lineNumber":66,"sourceCode":"\tif raw == \"\" {\n\t\treturn nil, fmt.Errorf(\"draft raw EML is empty\")\n\t}\n\tif len(raw) > maxRawEMLSize {\n\t\treturn nil, fmt.Errorf(\"draft raw EML is too large (%d bytes, max %d)\", len(raw), maxRawEMLSize)\n\t}\n\tdecoders := []func(string) ([]byte, error){\n\t\tbase64.URLEncoding.DecodeString,\n\t\tbase64.RawURLEncoding.DecodeString,\n\t\tbase64.StdEncoding.DecodeString,\n\t\tbase64.RawStdEncoding.DecodeString,\n\t}\n\tfor _, decode := range decoders {\n\t\tdecoded, err := decode(raw)\n\t\tif err == nil {\n\t\t\treturn normalizeLineEndings(decoded), nil\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"draft raw EML is not valid base64url\")\n}\n\nfunc normalizeLineEndings(in []byte) []byte {\n\tin = bytes.ReplaceAll(in, []byte(\"\\r\\n\"), []byte(\"\\n\"))\n\tin = bytes.ReplaceAll(in, []byte(\"\\r\"), []byte(\"\\n\"))\n\treturn in\n}\n\nfunc parseHeaderBlock(raw []byte) ([]Header, []byte, error) {\n\traw = normalizeLineEndings(raw)\n\tsep := bytes.Index(raw, []byte(\"\\n\\n\"))\n\tif sep < 0 {\n\t\treturn nil, nil, fmt.Errorf(\"invalid EML: missing header/body separator\")\n\t}\n\theaderLines := strings.Split(string(raw[:sep]), \"\\n\")\n\theaders := make([]Header, 0, len(headerLines))\n\tfor _, line := range headerLines {\n\t\tif strings.TrimSpace(line) == \"\" {","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/shortcuts/mail/draft/parse.go#L48-L84","documentation":"decodeRawEML expects the EML as base64url text (it tries standard and raw variants of URL and Std alphabets, then falls back to treating input as raw EML bytes elsewhere). If every decoder fails, the input is neither valid base64 nor was it pre-decoded. The error aggregates all decoder failures into one message.","triggerScenarios":"Passing already-decoded EML text (starting with 'Message-ID:' etc.) directly to Parse, passing base64 with an unsupported alphabet/whitespace/URL-safe mixing beyond the four decoders, or truncated base64 with wrong padding.","commonSituations":"Confusing the raw EML body with its encoded form after an API change, copying base64 with line breaks the decoder cannot tolerate in that variant, or double-encoding/decoding in a pipeline.","solutions":["Ensure the input is base64url-encoded (or try base64.StdEncoding first to check); decode/encode explicitly at your boundary","Strip whitespace/newlines before encoding: base64.URLEncoding.EncodeString([]byte(emlText))","Log decode errors per-variant locally to identify alphabet/padding issues"],"exampleFix":"// before\npart, err := draft.Parse(emlPlainText)\n// after\nencoded := base64.URLEncoding.EncodeString([]byte(emlPlainText))\npart, err := draft.Parse(encoded)","handlingStrategy":"validation","validationCode":"if _, err := base64.StdEncoding.DecodeString(strings.TrimSpace(rawEML)); err != nil {\n    if _, err2 := base64.RawURLEncoding.DecodeString(rawEML); err2 != nil {\n        return fmt.Errorf(\"raw EML is not base64: encode it before calling Parse\")\n    }\n}","typeGuard":"func isBase64(s string) bool {\n    for _, enc := range []*base64.Encoding{\n        base64.URLEncoding, base64.RawURLEncoding,\n        base64.StdEncoding, base64.RawStdEncoding,\n    } {\n        if _, err := enc.DecodeString(strings.TrimSpace(s)); err == nil {\n            return true\n        }\n    }\n    return false\n}","tryCatchPattern":"part, err := draft.Parse(rawEML)\nif err != nil && strings.Contains(err.Error(), \"not valid base64url\") {\n    encoded := base64.URLEncoding.EncodeString([]byte(rawEML))\n    part, err = draft.Parse(encoded)\n}","preventionTips":["Encode EML text with base64.URLEncoding.EncodeString immediately before Parse","Never pass plaintext EML directly into APIs documented as taking encoded content","Centralize encode-then-parse in one helper to avoid double-encoding mistakes"],"tags":["mail","draft","base64","encoding"],"backgroundTag":"invalid-base64-encoding","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}