Short answer
Log the value you pass to .eq() or the insert. If it is "undefined" or empty, wait for the user or route param before running the query. If it is a number or a slug, query the column that holds it. If ids come from another auth provider, store them in a text column.
Rather not fix it yourself? App Fix Ticket starts with a fixed-price diagnosis, then a fixed price for the fix before any fix work.
Where the bad value comes from, and the fix
01
The id is undefined when the query runs
“22P02 invalid_text_representation” PostgreSQL docs, PostgreSQL error codes
A query that runs before the session or the route param loads can send the text "undefined" or "null" as the id. Postgres can’t read that as a UUID. Skip the query until the value exists. Check ids read from the URL or local storage too: a stored "undefined" string is the same bug, and so is one bad entry in an .in() list.
// inside an async function const { data: { user } } = await supabase.auth.getUser(); if (!user) return; // no session yet: don't query const { data, error } = await supabase .from('profiles') .select('*') .eq('id', user.id) .single(); if (error?.code === '22P02') console.error('bad uuid', user.id);02
A form sends an empty string
An empty select or hidden field sends "" for a foreign key. Send null instead, and make the column nullable if the link is optional.
const row = { title, category_id: categoryId || null };03
A number or slug goes into a uuid column
“A UUID is written as a sequence of lower-case hexadecimal digits, in several groups separated by hyphens” PostgreSQL docs, UUID type
A route like /posts/12 or /posts/my-first-post passes 12 or a slug, but the id column is uuid. Filter on the column that holds that value, such as slug, or link with the UUID.
04
User ids come from another auth provider
Firebase, Clerk and other providers use ids that aren’t UUIDs, such as user_2abc. A user_id column of type uuid rejects them. Store those ids in a text column, or map each user to a Supabase auth user. After the change, rewrite RLS policies that use auth.uid() so they compare text with text, or they fail with operator does not exist: uuid = text.
-- Back up first. Foreign keys to auth.users(id), views and policies that use -- this column must be dropped and rebuilt. With Clerk or Firebase ids, -- compare against (auth.jwt() ->> 'sub') in your policies. alter table public.orders alter column user_id type text using user_id::text;05
The format is fine, the characters aren’t
“PostgreSQL also accepts the following alternative forms for input: use of upper-case digits, the standard format surrounded by braces, omitting some or all hyphens” PostgreSQL docs, UUID type
Postgres accepts upper case, braces and missing hyphens, so formatting is rarely the cause. A stray space, quote marks or a cut-off id is. Trim the value and check it has 32 hex digits.
Checked against the vendor’s docs on : PostgreSQL docs: UUID type; PostgreSQL docs: Error codes.
Rather hand it over?
Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.
- from $450App Fix TicketOne reproducible bug in an existing mobile or web app, diagnosed and fixed.See scope and start
- from $450AI-Built App RescueA Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.See scope and start
“Very responsive, attentive to fixing bugs, and completed the project as needed! Thank you!”
Related: Supabase operator does not exist: uuid = text · Supabase select returns an empty array · Supabase PGRST116 single row · Supabase value too long for type character varying