Home / RLS / Fix PGRST202: Could not find the function · Em português
Supabase · Error fix
Fix PGRST202: Could not find the function in the schema cache
The Data API looks a function up by name and by the names of the arguments you send. If you call rpc('get_orders', { userId }) and the function's parameter is p_user_id, it isn't found. Send the exact parameter names, keep the function in an exposed schema, and reload the cache after creating it.
01 Read the message
response
{
"code": "PGRST202",
"message": "Could not find the function public.get_orders(userId) in the schema cache"
}
The parentheses list the argument names your client sent, not the function's. Compare them with the definition: that mismatch is the most common cause. HTTP status is 404.
02 The causes
Argument names don't match
RPC arguments are matched by name. The function below must be called with p_user_id, not userId or user_id.
The function isn't in an exposed schema
Only schemas listed in the Data API settings are served. A function in private is invisible to rpc(), which is usually what you want for helpers.
A stale cache
The function was just created or its signature changed.
function and call
create function public.get_orders(p_user_id uuid) returns setof orders language sql stable as $$ select * from public.orders where user_id = p_user_id $$; -- client: the key must be the parameter name -- await supabase.rpc('get_orders', { p_user_id: user.id }) notify pgrst, 'reload schema'; -- after creating or changing it
03 The error you'll hit next: permissions
Once it's found, the caller's role needs execute, or the error becomes 42501 permission denied for function get_orders. Grant only the roles that should call it:
revoke execute on function public.get_orders(uuid) from public, anon; grant execute on function public.get_orders(uuid) to authenticated;
New functions are executable by everyone by default (Postgres grants execute to public), so revoke first if the function shouldn't be public. A security definer function bypasses RLS: list the ones anon can call.
04 Two functions with the same name
Overloads that differ only in types give a different error, PGRST203 Could not choose the best candidate function. Rename one or give the parameters different names.
Is your app leaking right now?
Paste your live URL. The scanner reads your page and its JavaScript for a Supabase service_role key, the one leak that skips every policy in this guide.
Catch this before it ships
airlock-rls is a CI gate that fails your build when a table ships exposed or a policy is permissive: the same class of bug, caught in CI against a database with your migrations applied, before it reaches prod.
Or start from nextjs-supabase-starter : auth + a table with RLS + an isolation test, so you start from a pattern that's already sealed.
Grab the Supabase RLS cheat sheet
The golden rules, the footguns that leak in prod, correct policy snippets, and the isolation test — on one page.
FAQ
It works in the SQL editor. Why not through rpc()?
The SQL editor calls the function directly with positional or named arguments and as a privileged role. rpc() goes through the Data API, which matches by argument names, only sees exposed schemas, and runs as anon or authenticated.
Does the order of the arguments matter?
No. The Data API matches arguments by name, so order doesn't matter, but every name has to exist in the function's parameter list.