Skip to content

fix(postgrest): use POST for rpc() with get:true and object args#2530

Open
PedroHenrique0713 wants to merge 1 commit into
supabase:masterfrom
PedroHenrique0713:fix/postgrest-rpc-get-object-args
Open

fix(postgrest): use POST for rpc() with get:true and object args#2530
PedroHenrique0713 wants to merge 1 commit into
supabase:masterfrom
PedroHenrique0713:fix/postgrest-rpc-get-object-args

Conversation

@PedroHenrique0713

Copy link
Copy Markdown
Contributor

🔍 Description

What changed?

rpc() has a guard (_hasObjectArg) that falls back to POST + JSON body when an argument is an object or array-of-objects, because objects cannot be serialized into URL query params. This guard previously only checked head — it now checks head || get.

The Prefer: return=minimal header is now only set when head is true (a get: true call wants the response data back, so it must not request a minimal response).

Why was this change needed?

A call like:

await supabase.rpc("fn", { data: { key: "value" } }, { get: true })

fell into the GET branch because _hasObjectArg was head && ... (false when head is false). The object was then serialized into the URL as [object Object] — silently corrupting the request. PostgREST would receive ?data=[object Object] instead of the intended JSON body.

The head: true path was already correct (it triggered the POST fallback and set return=minimal). This PR extends the same behavior to get: true, minus the return=minimal header (since get wants the response payload).

📸 Screenshots/Examples

// Before: GET /rpc/fn?data=[object Object]  — silently broken
// After:  POST /rpc/fn  body={"data":{"key":"value"}}  — correct
await supabase.rpc("fn", { data: { key: "value" } }, { get: true })

🔄 Breaking changes

  • This PR contains no breaking changes

Calls with primitive args (strings, numbers, arrays of primitives) are unaffected — they still use GET with URL params as before.

📋 Checklist

  • I have read the Contributing Guidelines
  • My PR title follows the conventional commit format: fix(postgrest): ...
  • I have run pnpm nx format to ensure consistent code formatting
  • I have added tests for new functionality (if applicable)
  • I have updated documentation (if applicable)

📝 Additional notes

Validated E2E: 3/3 tests pass. The first two tests inspect the wire (method/body/headers) via a mock fetch since the test DB has no function that accepts a jsonb arg; the third test hits the real PostgREST server to confirm the primitive-arg get: true path is unchanged.

Local checks: jest test/rpc-get-object-args.test.ts → 3 passed, tsc --noEmit → clean, prettier --check → clean.

rpc() has a guard (_hasObjectArg) that falls back to POST + JSON body when
an arg is an object or array-of-objects, since objects can't be serialized
to URL params. The guard only checked head, not get — so a call like

  supabase.rpc('fn', { data: { key: 'value' } }, { get: true })

fell into the GET branch and serialized the object as [object Object] in
the URL, silently corrupting the request.

Now (head || get) triggers the POST fallback. The return=minimal Prefer
header is only set when head (get:true wants the response data back, so
it must not request a minimal response).

Validated E2E: 3/3 tests pass (wire inspection via mock fetch for the
object-arg cases; real server for the primitive-arg case). tsc clean,
prettier clean.
@PedroHenrique0713
PedroHenrique0713 requested review from a team as code owners July 15, 2026 18:04
@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 99b34f86-a68d-45a1-82e2-5a1df85a3e06

📥 Commits

Reviewing files that changed from the base of the PR and between 5c18b62 and 5d0054b.

📒 Files selected for processing (2)
  • packages/core/postgrest-js/src/PostgrestClient.ts
  • packages/core/postgrest-js/test/rpc-get-object-args.test.ts

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Improved RPC requests with object arguments when using GET options.
    • Prevented object values from being incorrectly serialized into request URLs.
    • Preserved minimal-response behavior for HEAD requests.
    • Confirmed that RPC requests with primitive arguments continue using GET as expected.

Walkthrough

PostgrestClient.rpc now sends object-valued arguments using POST when get: true or head: true is specified. return=minimal is applied only to object-argument requests using head: true, while count preferences remain available for other requests. New tests verify POST bodies, header behavior, and the existing GET path for primitive arguments.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install timed out. The project may have too many dependencies for the sandbox.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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.

1 participant