P0002ERRORTier 2 — Caution✅ HIGH confidenceno_data_found
What this means
A SELECT INTO or FETCH statement inside a PL/pgSQL function returned no rows, and the function was not written to handle that case gracefully.
Why it happens
- 1SELECT INTO in PL/pgSQL returned zero rows and STRICT mode is used, or explicit check raises exception
- 2FETCH on a cursor that has been exhausted
- 3Function expected exactly one row from a query but the table is empty or the WHERE clause matched nothing
How to reproduce
PL/pgSQL function using SELECT INTO STRICT or explicit NOT FOUND check
CREATE OR REPLACE FUNCTION get_user(uid int) RETURNS text AS $
DECLARE
uname text;
BEGIN
SELECT name INTO STRICT uname FROM users WHERE id = uid;
RETURN uname;
END;
$ LANGUAGE plpgsql;
SELECT get_user(99999); -- user 99999 does not existFix 1: Handle NOT FOUND in an EXCEPTION block
Zero rows is a valid expected outcome
BEGIN
SELECT name INTO STRICT uname FROM users WHERE id = uid;
EXCEPTION WHEN no_data_found THEN
RETURN NULL; -- or a default value
END;Why this works
Catches P0002 and returns a sensible default instead of propagating the error
Fix 2: Use SELECT INTO without STRICT and check FOUND
Zero rows is acceptable and you want to handle it inline
SELECT name INTO uname FROM users WHERE id = uid;
IF NOT FOUND THEN
RETURN NULL;
END IF;Why this works
Without STRICT, SELECT INTO does not raise P0002; use the FOUND variable instead
What not to do
Do not use SELECT INTO STRICT for queries that may legitimately return no rows without handling no_data_found
Why it's wrong: Will raise an unhandled exception on empty results
Sources
📚 Official docs: https://www.postgresql.org/docs/current/plpgsql-statements.html#PLPGSQL-STATEMENTS-SQL-ONEROW
🔧 Source ref: https://www.postgresql.org/docs/current/errcodes-appendix.html
Confidence assessment
✅ HIGH confidence
Well-documented PL/pgSQL error; extremely common in production stored procedures.
See also
🔗 Related errors
📄 Reference pages