{"record":{"id":"1a0f95c7645920e7","repo":"chenhg5/cc-connect","slug":"wecom-ws-empty-aeskey","errorCode":null,"errorMessage":"wecom-ws: empty aeskey","messagePattern":"wecom-ws: empty aeskey","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/wecom/websocket_media.go","lineNumber":207,"sourceCode":"\t\tif body.MsgType == \"file\" && body.File != nil {\n\t\t\tappendFile(&current, body.File.URL, body.File.Aeskey, false)\n\t\t}\n\t\tif body.MsgType == \"image\" && body.Image != nil {\n\t\t\tappendImage(&current, body.Image.URL, body.Image.Aeskey, false)\n\t\t}\n\t}\n\twalkQuote(body.Quote)\n\treturn current, quoted\n}\n\n// decodeWeComAESKey normalizes and decodes the aeskey from WeCom WS callbacks.\n// The server may send standard Base64, URL-safe Base64 (- _), omit padding, insert\n// whitespace, or (rarely) a 64-char hex string. Node's Buffer.from(s, 'base64') is more\n// permissive than Go's StdEncoding; we mirror common cases so decryption matches the SDK.\nfunc decodeWeComAESKey(aesKey string) ([]byte, error) {\n\ts := strings.TrimSpace(aesKey)\n\tif s == \"\" {\n\t\treturn nil, fmt.Errorf(\"wecom-ws: empty aeskey\")\n\t}\n\tvar b strings.Builder\n\tb.Grow(len(s))\n\tfor i := 0; i < len(s); i++ {\n\t\tswitch s[i] {\n\t\tcase '\\n', '\\r', ' ', '\\t':\n\t\t\tcontinue\n\t\tdefault:\n\t\t\tb.WriteByte(s[i])\n\t\t}\n\t}\n\ts = b.String()\n\n\tif len(s) == 64 && isHexString(s) {\n\t\tkey, err := hex.DecodeString(s)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"wecom-ws: decode aeskey hex: %w\", err)\n\t\t}","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/wecom/websocket_media.go#L189-L225","documentation":"Guard at the top of decodeWeComAESKey: the aeskey string accompanying an inbound WeCom media message (image/file) is empty, so there is no key to decrypt the downloaded ciphertext. The key normally arrives on every media callback body, so an empty value means a malformed or unexpected callback payload.","triggerScenarios":"Thrown at platform/wecom/websocket_media.go:207 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Skip the media item and notify/log rather than retrying — the callback payload itself is incomplete","Verify the callback schema version expected from the WeCom AI-Bot WS feed","Guard upstream in the media walker so attachments without aeskey are ignored individually without failing the whole message"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"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"}