From 8189b79e21b642435b21b75414b8ca7bad37b90d Mon Sep 17 00:00:00 2001 From: Matin Gathani Date: Thu, 2 Apr 2026 13:15:48 -0700 Subject: [PATCH] fix(blob): include HTTP status in error when client token retrieval fails Replaces the vague 'Failed to retrieve the client token' message (also fixing the double-space typo) with one that includes the HTTP status code and status text, making auth errors (401, 403) easier to diagnose. Closes #488 --- .../fix-blob-client-token-error-message.md | 11 +++++++++++ packages/blob/src/client.browser.test.ts | 19 +++++++++++++++++++ packages/blob/src/client.ts | 4 +++- 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 .changeset/fix-blob-client-token-error-message.md diff --git a/.changeset/fix-blob-client-token-error-message.md b/.changeset/fix-blob-client-token-error-message.md new file mode 100644 index 000000000..e28d28a4f --- /dev/null +++ b/.changeset/fix-blob-client-token-error-message.md @@ -0,0 +1,11 @@ +--- +"@vercel/blob": patch +--- + +fix(blob): include HTTP status in error when client token retrieval fails + +When `upload()` fails to retrieve a client token from `handleUploadUrl` +(e.g. the route returns 401, 403, or 500), the error message now includes +the HTTP status code and status text to help with debugging. + +Closes #488 diff --git a/packages/blob/src/client.browser.test.ts b/packages/blob/src/client.browser.test.ts index d86f29c9d..348a2a414 100644 --- a/packages/blob/src/client.browser.test.ts +++ b/packages/blob/src/client.browser.test.ts @@ -163,6 +163,25 @@ describe('client', () => { }, ); }); + + it('throws with HTTP status when handleUploadUrl returns an error', async () => { + jest.spyOn(undici, 'fetch').mockImplementation( + jest.fn().mockResolvedValueOnce({ + status: 403, + statusText: 'Forbidden', + ok: false, + }), + ); + + await expect( + upload('foo.txt', 'Test file data', { + access: 'public', + handleUploadUrl: '/api/upload', + }), + ).rejects.toThrow( + 'Vercel Blob: Failed to retrieve the client token: 403 Forbidden', + ); + }); }); describe('multipart upload', () => { diff --git a/packages/blob/src/client.ts b/packages/blob/src/client.ts index 8c7eb12f1..d3eb5e658 100644 --- a/packages/blob/src/client.ts +++ b/packages/blob/src/client.ts @@ -698,7 +698,9 @@ async function retrieveClientToken(options: { }); if (!res.ok) { - throw new BlobError('Failed to retrieve the client token'); + throw new BlobError( + `Failed to retrieve the client token: ${res.status} ${res.statusText}`, + ); } try {