fix(postgrest): pass request headers as plain object for RN/custom-fetch compatibility#2414
Merged
Merged
Conversation
@supabase/auth-js
@supabase/functions-js
@supabase/postgrest-js
@supabase/realtime-js
@supabase/storage-js
@supabase/supabase-js
commit: |
36829dd to
83b4b87
Compare
83b4b87 to
eca699f
Compare
avallete
approved these changes
Jun 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Passes request headers to the user-supplied
fetchas a plain object instead of aHeadersinstance. Picks up the intent of #2017 from @dev-hari-prasad with a minimal, focused change.Why
React Native's XHR-based
fetchpolyfill (whatwg-fetch) silently drops headers — most notablyContent-Type— when given aHeadersinstance. WithoutContent-Type: application/json, PostgREST cannot parse the JSON body, and a parameter-lessrpc()call surfaces as a confusingPGRST202("Searched for the function with a single unnamed text parameter").See:
supabase-jsrpc()fails withPGRST202for parameter-less functions in React Native #1562 (the original bug report)Alignment with sibling packages
The sibling clients have always handled headers as plain objects internally and at the
fetchcall site:auth-js—src/lib/fetch.tsspreads{ 'Content-Type': '...', ...options?.headers }into request params.storage-js—BaseApiClient.headers: { [key: string]: string }.functions-js—FunctionsClient.headers: Record<string, string>.postgrest-jswas the outlier: a previous refactor (postgrest-js#619, "chore: refactor in favor of Headers API") moved it to wrap headers innew Headers(...)at the fetch boundary, primarily to get ergonomic multi-value handling for thePreferheader.This PR keeps that ergonomic win — the internal
this.headersstorage stays aHeadersinstance, soPreferappend-style construction continues to work as designed — and only flattens to a plain object at the moment of the_fetch()call. Wire-level behavior to PostgREST is unchanged on standard runtimes (native fetch normalizes either form); the change only affects what user-supplied fetch wrappers see.Behavior note for custom fetch consumers
Headers handed to a user-supplied
fetchare now a plainRecord<string, string>with lowercase keys (perHeaders.prototype.forEachsemantics). Wrappers that previously didreq.headers.get('Content-Type')should switch toreq.headers['content-type'].Tests
test/headers-serialization.test.ts— asserts the request handed to a custom fetch hascontent-type: application/jsonreachable by plain-object key access (i.e. what the RN polyfill would see).test/fetch-errors.test.ts,test/retry.test.ts,test/basic.test.tsto reflect the plain-object shape on the wire.Closes #1562.