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

  1. 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.
  2. Bypass or configure proxies to forward x-encrypted-param; test from a different network.
  3. Retry the upload; transient CDN inconsistencies can resolve themselves.
  4. 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

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


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/eef30e6fda703ccc. Report an issue: GitHub.