{"record":{"id":"fa8a4b206ccf38b9","repo":"chenhg5/cc-connect","slug":"s-aes-key-base64-w","errorCode":null,"errorMessage":"%s: aes_key base64: %w","messagePattern":"(.+?): aes_key base64: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/weixin/cdn.go","lineNumber":94,"sourceCode":"\tif len(ciphertext)%aes.BlockSize != 0 {\n\t\treturn nil, fmt.Errorf(\"ciphertext length %d not aligned to block\", len(ciphertext))\n\t}\n\tblock, err := aes.NewCipher(key)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tout := make([]byte, len(ciphertext))\n\tfor i := 0; i < len(ciphertext); i += aes.BlockSize {\n\t\tblock.Decrypt(out[i:i+aes.BlockSize], ciphertext[i:i+aes.BlockSize])\n\t}\n\treturn pkcs7Unpad(out, aes.BlockSize)\n}\n\n// parseAesKey decodes CDNMedia.aes_key: base64(raw 16 bytes) or base64(32-char hex ASCII) → 16 bytes.\nfunc parseAesKey(aesKeyBase64, label string) ([]byte, error) {\n\tdecoded, err := base64.StdEncoding.DecodeString(strings.TrimSpace(aesKeyBase64))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"%s: aes_key base64: %w\", label, err)\n\t}\n\tif len(decoded) == 16 {\n\t\treturn decoded, nil\n\t}\n\tif len(decoded) == 32 {\n\t\ts := string(decoded)\n\t\tif hex32RE.MatchString(s) {\n\t\t\tk, err := hex.DecodeString(s)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"%s: aes_key hex inside base64: %w\", label, err)\n\t\t\t}\n\t\t\treturn k, nil\n\t\t}\n\t}\n\treturn nil, fmt.Errorf(\"%s: aes_key must be 16 raw bytes or 32-char hex (base64-wrapped), got %d bytes after base64\", label, len(decoded))\n}\n\nfunc buildCdnDownloadURL(encryptedQueryParam, cdnBase string) string {","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/weixin/cdn.go#L76-L112","documentation":"parseAesKey decodes the CDNMedia.aes_key field, which must be base64 encoding of either 16 raw key bytes or 32 hex-ASCII characters; if base64.StdEncoding.DecodeString fails (invalid characters, wrong length mod 4, padding issues) the error is wrapped as '<label>: aes_key base64: %w' with the underlying base64 error. The label identifies which media/URL the bad key came from.","triggerScenarios":"The aes_key field contains a raw (non-base64) hex string like 'a1b2...' passed straight in; whitespace/newlines beyond what TrimSpace removes (internal spaces); URL-safe base64 ('-','_') instead of standard base64; the API returned an empty or placeholder aes_key; JSON marshaling mangled the field.","commonSituations":"WeChat Work API responses where aes_key is missing and an empty string is decoded (DecodeString('') succeeds but the follow-on length check fails — this error fires for truly malformed base64); hand-editing config files; logging/copy mistakes truncating the key.","solutions":["Check the raw aes_key string: it must be valid standard base64 (length %4==0 after TrimSpace, only A-Za-z0-9+/=)","If the key is raw hex (32 chars), wrap it: base64.StdEncoding.EncodeToString([]byte(hexStr)) or hex-decode it yourself to 16 bytes and pass those","Confirm the CDN API response actually populated aes_key; re-fetch the media metadata if empty","Use base64.RawStdEncoding or sanitize URL-safe characters if the upstream uses -/_","Log the label in the wrapped error to identify which media item's key is malformed"],"exampleFix":"// before\nkey, err := parseAesKey(rawHexKey, \"cdn\") // raw hex is not base64\n// after\nif isHex(rawHexKey) && len(rawHexKey) == 32 {\n    rawHexKey = base64.StdEncoding.EncodeToString([]byte(rawHexKey))\n}\nkey, err := parseAesKey(rawHexKey, \"cdn\")","handlingStrategy":"validation","validationCode":"k := strings.TrimSpace(media.AesKey)\nif k == \"\" { return errors.New(\"aes_key missing\") }\nif _, err := base64.StdEncoding.DecodeString(k); err != nil {\n    return fmt.Errorf(\"aes_key not valid base64: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"key, err := parseAesKey(media.AesKey, media.URL)\nif err != nil {\n    var b64 base64.CorruptInputError\n    if errors.As(err, &b64) {\n        log.Warn(\"aes_key not standard base64; trying url-safe/hex fallback\")\n        return tryFallbackKeyDecodings(media.AesKey)\n    }\n    return err\n}","preventionTips":["Validate aes_key format (standard base64, decodes to 16 or 32 bytes) as soon as the CDN metadata arrives","Normalize URL-safe base64 (-/_) to standard (+//) before parsing","Never truncate or reformat aes_key strings when logging or persisting them","Keep the label/URL in the error so the offending media item is identifiable"],"tags":["weixin","base64","crypto","key-parsing"],"backgroundTag":"invalid-argument-format","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"}