HKUDS/Vibe-Trading · error · RuntimeError
CDN upload response missing x-encrypted-param header; status
Error message
CDN upload response missing x-encrypted-param header; status={cdn_resp.status_code} headers={dict(cdn_resp.headers)} What it means
After POSTing the AES-encrypted file to the CDN, the channel reads the x-encrypted-param response header, which becomes the download param embedded in the final message. If the header is missing, it raises RuntimeError with the CDN status code and all response headers, because recipients would be unable to download the media without it.
Source
Thrown at agent/src/channels/weixin.py:1422
cdn_upload_url = upload_full_url
else:
cdn_upload_url = (
f"{self.config.cdn_base_url}/upload"
f"?encrypted_query_param={quote(upload_param)}"
f"&filekey={quote(file_key)}"
)
cdn_resp = await self._client.post(
cdn_upload_url,
content=encrypted_data,
headers={"Content-Type": "application/octet-stream"},
)
cdn_resp.raise_for_status()
# The download encrypted_query_param comes from CDN response header
download_param = cdn_resp.headers.get("x-encrypted-param", "")
if not download_param:
raise RuntimeError(
"CDN upload response missing x-encrypted-param header; "
f"status={cdn_resp.status_code} headers={dict(cdn_resp.headers)}"
)
# Step 3: Send message with the media item
# aes_key for CDNMedia is the hex key encoded as base64
# (matches: Buffer.from(uploaded.aeskey).toString("base64"))
cdn_aes_key_b64 = base64.b64encode(aes_key_hex.encode()).decode()
media_item: dict[str, Any] = {
"media": {
"encrypt_query_param": download_param,
"aes_key": cdn_aes_key_b64,
"encrypt_type": 1,
},
}
if item_type == ITEM_IMAGE:View on GitHub (pinned to 80ffdda44c)
Solutions
- Inspect status and headers in the message: if content-type is text/html, the request hit a gateway, not the CDN — fix routing/base URL.
- Bypass or configure proxies to forward x-encrypted-param; test from a different network.
- Retry the upload; transient CDN inconsistencies can resolve themselves.
- Verify the encrypted payload and content-length were sent intact (compare with a known-good small image upload).
Example fix
// before
cdn_resp = await client.post(upload_url, content=encrypted)
cdn_resp.raise_for_status()
// after
cdn_resp = await client.post(upload_url, content=encrypted)
cdn_resp.raise_for_status()
if "x-encrypted-param" not in cdn_resp.headers:
self.logger.warning("CDN dropped header, retrying; resp={}", cdn_resp.text[:200])
cdn_resp = await client.post(upload_url, content=encrypted)
cdn_resp.raise_for_status() Defensive patterns
Strategy: retry
Try / catch
try:
await channel.send_media(chat_id, path)
except RuntimeError as e:
if "x-encrypted-param" in str(e):
await asyncio.sleep(5)
await channel.send_media(chat_id, path) # retry CDN upload
else:
raise Prevention
- Ensure proxies/gateways forward x-* response headers.
- Verify CDN base URL routing is not intercepted by an HTML gateway.
- Retry transient CDN inconsistencies with a small backoff.
When it happens
Trigger: CDN upload returns 2xx (raise_for_status passed) but without an x-encrypted-param header — e.g. proxy/CDN stripping custom headers, a gateway error page returning 200, or a server-side upload that silently failed.
Common situations: Corporate proxies or middleboxes dropping unknown x-* headers; regional CDN nodes with different behavior; response actually being an HTML error body with 200 status; partial upload where the CDN stored nothing.
Related errors
- unsafe media URL: {error}
- Failed to get QR code from WeChat API: {data}
- WeChat session paused, {remaining_min} min remaining (errcod
- getUpdates failed: ret={ret} errcode={errcode} errmsg={data.
- WeChat client not initialized or not authenticated
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/eef30e6fda703ccc.
Report an issue: GitHub.