supabase / supabase-js

An isomorphic Javascript client for Supabase. Query your Supabase database, subscribe to realtime events, upload and download files, browse typescript examples, invoke postgres functions via rpc, invoke supabase edge functions, query pgvector.
https://supabase.com
MIT License
2.86k stars 220 forks source link

v2.0.0 regression: Supabase JS fails when run inside script (TSX) #691

Closed ajay1495 closed 1 year ago

ajay1495 commented 1 year ago

Bug report

Describe the bug

In a script, Supabase JS V2 doesn't work when doing any insert or update operation.

The error:

{
  error: {
    code: 'PGRST102',
    details: null,
    hint: null,
    message: 'Content-Type not acceptable: application/json, text/plain'
  },
  data: null,
  count: null,
  status: 400,
  statusText: 'Bad Request'
}

To Reproduce

The TSX package is a common tool used to execute TypeScript scripts: https://www.npmjs.com/package/tsx

After installing, insert the following inside script.tsx:

import { createClient } from "@supabase/supabase-js";

async function main() {
  const clientSupabase = createClient(SUPABASE_URL, SUPABASE_KEY);
  const testres1 = await clientSupabase.from("some_table").select();
  console.log(testres1.data?.length); // succeeds

  const testres = await clientSupabase.from("some_table").insert({
    email: "test@gmail.com",
  });

  console.log(testres); // returns an error 
}

main();

Then run npx tsx ./src/script.ts.

Github repo to reproduce: https://github.com/ajay1495/supabase-playground

Expected behavior

Successful insert.

System information

Additional context

Select operations work fine, it seems to fail when running any request involving sending a payload. Perhaps a header needs to be set somewhere.

Additionally, this used to work in Supabase V1, so this appears to be a regression in upgrading to Supabase V2.

j4w8n commented 1 year ago

I believe you need brackets in there. Or maybe not. My api docs show them, even for one column insert; but the javascript reference does not.

const testres = await clientSupabase.from("some_table").insert([
  { email: "test@gmail.com", }
]);
j4w8n commented 1 year ago

I was wrong about the brackets.

Would it be the trailing comma though? That would be invalid json, if I recall.

ajay1495 commented 1 year ago

Hmm no I don't think so, the trailing comma isn't the issue since it's a TypeScript object and not JSON directly

I suspect it has something to do with the Supabase JS library, because that exact code works when downgrading to V1, but fails for V2.

mstade commented 1 year ago

I am not using TypeScript, and seeing this exact same error. Keen to know if there's a known good version of 2.x?

akella commented 1 year ago

Not using Typescript, using Next.js with js. Seing exactly same error as @ajay1495 when i ran my INSERT from API Handler like this:

// pages/api/insert.js
import {supabase} from './supabase'

const handler = async (req, res) => {
    let insert_result = await supabase.from('items').insert({'name': 'whatever',})

    res.send({message: 'ok ok',insert_result})
}

export default handler;

(SELECT works just fine from backend, probably because doesnt have payload)

Same INSERT code works just fine from client side components. I looked at the logs of both requests and difference seems to be only in header, correct one: "content_type": "application/json", The one thats generated by calling from handler in my case: "content_type": "application/json, text/plain;charset=UTF-8",

Seing this in latest 2.7.0

akella commented 1 year ago

Just wanted to elaborate a little and update this. So when you sell something with the help of Supabase, stripe/paddle - they need to talk to your backend webhooks, so you can update your database with user purchase. Currently it is not possible. Because backend supabase sends wrong(not-accepted) headers. This kind of breaks this basic functionality.

UPDATE: I investigated and found out that i have this error on Node 18.1.0, and i dont have it on Node 16.15.0. So this is related to something inside node. This solves it for me, i hope it helps someone else too

mkandan commented 1 year ago

Bumping this, a Node 18 support/fix for this would be wonderful

soedirgo commented 1 year ago

@akella thanks for the find - I was able to reproduce this on @ajay1495's repo using Node 18.1.0. Upgrading to Node 18.2.0+ seems to fix this though, can you try that out?

@steve-chavez should PostgREST be rejecting Content-Type: application/json, text/plain;charset=UTF-8?

akella commented 1 year ago

@soedirgo updated to 18.14.0, works for me!

steve-chavez commented 1 year ago

should PostgREST be rejecting Content-Type: application/json, text/plain;charset=UTF-8?

@soedirgo Hm, that looks like a malformed Content-Type, according to spec it should be a "singleton field"(unlike Accept which can contain multiple values).

Although Content-Type is defined as a singleton field, it is sometimes incorrectly generated multiple times, resulting in a combined field value that appears to be a list. Recipients often attempt to handle this error by using the last syntactically valid member of the list, leading to potential interoperability and security issues if different implementations have different error handling behaviors.

PostgREST accepts both text/plain and application/json, with a different processing for each one, I'm not sure if we can decide for the user which one is preferred.

IIUC, this is a bug that was fixed in Node itself?


One thing we could do in PostgREST is to enrich the error message with a link to error docs, there we could add a warning regarding Node versions.

ajay1495 commented 1 year ago

Great find @akella @soedirgo ! Upgrading to Node 18.14.0 fixed for me as well.

Thanks for your help.

One thing we could do in PostgREST is to enrich the error message with a link to error docs, there we could add a warning regarding Node versions.

I agree. Given the cryptic nature of the error message, it would save folks using older versions of Node many hours of debugging.

soedirgo commented 1 year ago

that looks like a malformed Content-Type

Good to know! It does seem like a bug in Node that's been fixed, though I couldn't find a reference to the issue. Marking this as closed - thanks for the find folks!