From 959938fbe34f6abebb4c19e2b90c7757d49f7b6c Mon Sep 17 00:00:00 2001 From: "Tao Sun (from Dev Box)" Date: Mon, 20 Jul 2026 10:59:41 +0800 Subject: [PATCH] fix(weixin): drop manual Content-Length header rejected by undici (#55) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit buildHeaders() set a manual Content-Length on every WeChat API request. The gateway's bundled undici rejects a manually-set Content-Length with InvalidArgumentError: invalid content-length header (UND_ERR_INVALID_ARG), surfaced as 'TypeError: fetch failed'. Since buildHeaders() is used by every call (getUpdates, sendMessage, sendTyping, getConfig, getUploadUrl), the whole channel failed and WeChat showed '暂无法连接 OpenClaw'. Let fetch/undici compute Content-Length from the body automatically. Fixes #55 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- plugins/openclaw-weixin/src/api/api.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/plugins/openclaw-weixin/src/api/api.ts b/plugins/openclaw-weixin/src/api/api.ts index 8e2a6c7..27b4764 100644 --- a/plugins/openclaw-weixin/src/api/api.ts +++ b/plugins/openclaw-weixin/src/api/api.ts @@ -65,11 +65,10 @@ function randomWechatUin(): string { return Buffer.from(String(uint32), "utf-8").toString("base64"); } -function buildHeaders(opts: { token?: string; body: string }): Record { +function buildHeaders(opts: { token?: string }): Record { const headers: Record = { "Content-Type": "application/json", AuthorizationType: "ilink_bot_token", - "Content-Length": String(Buffer.byteLength(opts.body, "utf-8")), "X-WECHAT-UIN": randomWechatUin(), }; if (opts.token?.trim()) { @@ -99,7 +98,7 @@ async function apiFetch(params: { }): Promise { const base = ensureTrailingSlash(params.baseUrl); const url = new URL(params.endpoint, base); - const hdrs = buildHeaders({ token: params.token, body: params.body }); + const hdrs = buildHeaders({ token: params.token }); logger.debug(`POST ${redactUrl(url.toString())} body=${redactBody(params.body)}`); const controller = new AbortController();