Skip to content

fix(auth): add toJSON to AuthError for correct JSON serialization#2238

Merged
mandarini merged 2 commits intosupabase:masterfrom
oniani1:fix/auth-error-tojson
Apr 15, 2026
Merged

fix(auth): add toJSON to AuthError for correct JSON serialization#2238
mandarini merged 2 commits intosupabase:masterfrom
oniani1:fix/auth-error-tojson

Conversation

@oniani1
Copy link
Copy Markdown
Contributor

@oniani1 oniani1 commented Apr 9, 2026

Summary

JSON.stringify() silently drops the message field on most auth error classes because Error.prototype.message is non-enumerable.

Only 2 out of 13 auth error classes (AuthImplicitGrantRedirectError and AuthPKCEGrantCodeExchangeError) had toJSON() overrides. The rest -- including AuthApiError, which is by far the most commonly encountered -- would serialize without message:

const err = new AuthApiError('Invalid login credentials', 400, 'invalid_credentials')
JSON.stringify(err)
// Before: {"status":400,"code":"invalid_credentials"}  -- message is gone
// After:  {"name":"AuthApiError","message":"Invalid login credentials","status":400,"code":"invalid_credentials"}

This adds toJSON() to the AuthError base class (returning name, message, status, code), so all subclasses inherit it automatically. The two existing overrides now spread super.toJSON() instead of duplicating fields. AuthWeakPasswordError gets an override to include reasons.

Same pattern as the recent fixes for FunctionsError (#2226) and PostgrestError (#2212).

Test plan

  • Added errors.test.ts covering all 12 concrete error classes
  • Each test verifies JSON.stringify() round-trip preserves message and all relevant fields
  • Existing tests pass with no regressions

@oniani1 oniani1 requested review from a team as code owners April 9, 2026 18:08
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented Apr 9, 2026

Open in StackBlitz

@supabase/auth-js

npm i https://pkg.pr.new/@supabase/auth-js@2238

@supabase/functions-js

npm i https://pkg.pr.new/@supabase/functions-js@2238

@supabase/postgrest-js

npm i https://pkg.pr.new/@supabase/postgrest-js@2238

@supabase/realtime-js

npm i https://pkg.pr.new/@supabase/realtime-js@2238

@supabase/storage-js

npm i https://pkg.pr.new/@supabase/storage-js@2238

@supabase/supabase-js

npm i https://pkg.pr.new/@supabase/supabase-js@2238

commit: 7af2c87

Copy link
Copy Markdown
Contributor

@mandarini mandarini left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @oniani1, thank you so much for contributing to Supabase! 💚

This is a really nice fix. The base-class toJSON() approach is exactly the right call, and it lines up perfectly with what we did for FunctionsError (#2226) and PostgrestError (#2212). The tests are thorough and the super.toJSON() spread in the existing overrides is a clean de-duplication.

Two small things I wanted to flag before merging:

  1. AuthUnknownError.originalError: with the base toJSON(), this property won't appear in serialized output. I suspect that's fine (the original error could be circular or otherwise non-serializable), but wanted to confirm that's intentional on your end. If it is, could you add a quick test assertion that originalError is not present in the serialized output? That way nobody tries to "fix" it later without understanding the reasoning.

  2. code now appears in AuthImplicitGrantRedirectError and AuthPKCEGrantCodeExchangeError toJSON output: since both pass undefined for code, this is invisible through JSON.stringify (undefined gets dropped). But if someone calls .toJSON() directly, they'll now see code: undefined in the object. Not a blocker at all, just wanted to make sure you'd considered it.

Once you've confirmed the originalError point, this is good to go.

Thank you so much for contributing to Supabase!

Adds a test assertion confirming that AuthUnknownError.originalError
does not appear in JSON.stringify output, since the underlying error
could be circular or otherwise non-serializable.
@oniani1
Copy link
Copy Markdown
Contributor Author

oniani1 commented Apr 14, 2026

Yeah, the originalError exclusion is intentional. It's typed as unknown and could be circular or carry non-serializable properties, so including it in toJSON() would risk JSON.stringify throwing. Anyone who needs it can still grab err.originalError directly.

Added a test for that in 7af2c87.

On the code: undefined thing, agreed that's just how the super.toJSON() pattern works. JSON.stringify drops undefined values anyway so the serialized output isn't affected.

@mandarini mandarini merged commit 1dbc795 into supabase:master Apr 15, 2026
21 checks passed
mandarini pushed a commit to supabase/supabase that referenced this pull request Apr 16, 2026
This PR updates @supabase/*-js libraries to version 2.103.2.

**Source**: supabase-js-stable-release

**Changes**:
- Updated @supabase/supabase-js to 2.103.2
- Updated @supabase/auth-js to 2.103.2
- Updated @supabase/realtime-js to 2.103.2
- Updated @supabase/postgest-js to 2.103.2
- Refreshed pnpm-lock.yaml

---

## Release Notes

## v2.103.2

## 2.103.2 (2026-04-15)

### 🩹 Fixes

- **auth:** include Cloudflare error codes in NETWORK_ERROR_CODES
([#2239](supabase/supabase-js#2239))
- **auth:** remove Prettify wrapper from exported types for TypeDoc
expansion ([#2250](supabase/supabase-js#2250))
- **misc:** add explicit return types to toJSON methods for JSR compat
([#2252](supabase/supabase-js#2252))
- **storage:** remove client-side signed URL render endpoint
normalization
([#2249](supabase/supabase-js#2249))

### ❤️ Thank You

- Katerina Skroumpelou @mandarini
- Vansh Sharma @Vansh1811
## v2.103.1

## 2.103.1 (2026-04-15)

### 🩹 Fixes

- **auth:** add toJSON to AuthError for correct JSON serialization
([#2238](supabase/supabase-js#2238))
- **postgrest:** handle bigint rpc
([#2245](supabase/supabase-js#2245))
- **storage:** add toJSON to StorageError for correct JSON serialization
([#2246](supabase/supabase-js#2246))
- **storage:** apply empty transform check to download and getPublicUrl
([#2219](supabase/supabase-js#2219))

### ❤️ Thank You

- oniani1
- Vaibhav @7ttp

This PR was created automatically.

Co-authored-by: supabase-workflow-trigger[bot] <266661614+supabase-workflow-trigger[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants