From 04ccea62b9cc743e548b662734de903495b63da9 Mon Sep 17 00:00:00 2001 From: Sujin Kim Date: Fri, 29 May 2026 02:40:23 +0000 Subject: [PATCH] fix: send empty JSON body for non-GET requests with null body When body is null/undefined, newSignedRequest() was sending an empty string '' as the request body. Some backends now require at least a valid empty JSON body '{}' for POST/PATCH/DELETE requests. Send '{}' for non-GET/HEAD methods while keeping authBody as '' to preserve HMAC signatures for legacy (v<4) backends. --- packages/backend.ai-client/src/client.ts | 6 +++++- src/lib/backend.ai-client-node.ts | 7 ++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/backend.ai-client/src/client.ts b/packages/backend.ai-client/src/client.ts index b061ce5b51..05f746da0a 100644 --- a/packages/backend.ai-client/src/client.ts +++ b/packages/backend.ai-client/src/client.ts @@ -1680,7 +1680,11 @@ export class Client { let authBody: string; let d = new Date(); if (body === null || body === undefined) { - requestBody = ''; + // Some backends require a valid JSON body even when empty. + // Send '{}' for methods that carry a body; keep '' for GET/HEAD. + // authBody mirrors requestBody so the v<4 signature (which hashes the + // body) matches what is actually sent; v4+ excludes the body anyway. + requestBody = method !== 'GET' && method !== 'HEAD' ? '{}' : ''; authBody = requestBody; } else if ( typeof (body as { getBoundary?: () => string }).getBoundary === diff --git a/src/lib/backend.ai-client-node.ts b/src/lib/backend.ai-client-node.ts index d32608c7e0..c080be5bc1 100644 --- a/src/lib/backend.ai-client-node.ts +++ b/src/lib/backend.ai-client-node.ts @@ -1316,7 +1316,12 @@ class Client { let authBody; let d = new Date(); if (body === null || body === undefined) { - requestBody = ''; + // Some backends require a valid JSON body even when empty. + // Send '{}' for methods that carry a body; keep '' for GET/HEAD. + // authBody must match the actual body: on legacy (v<4) backends the + // signature hashes the body, so a mismatch fails verification. On v4+ + // the body is excluded from the signature (see below), so this is safe. + requestBody = method !== 'GET' && method !== 'HEAD' ? '{}' : ''; authBody = requestBody; } else if ( typeof body.getBoundary === 'function' ||