How to fix There is no parameter $N in PostgreSQL
This error occurs when your parameterized SQL query references a placeholder like $1 or $2, but the corresponding parameter value was not provided when executing the statement. This is typically a binding mismatch between your application code and the prepared statement.
Quick fix
Fixes There is no parameter $N
-- This query has 3 parameters: $1, $2, $3
SELECT * FROM users WHERE email = $1 AND status = $2 AND created > $3;- Count the parameter placeholders in your SQL query
- Check your application code for the matching parameter array
- Verify parameter order matches the SQL placeholders
- Test the query directly in psql to isolate the issue
-- This query has 3 parameters: $1, $2, $3SELECT * FROM users WHERE email = $1 AND status = $2 AND created > $3;There is no parameter $N
What this error means
SQLSTATE 42P02 (undefined_parameter) is raised when a PostgreSQL prepared statement or EXECUTE command references a parameter placeholder (such as $1, $2, $3, etc.) that has no corresponding value supplied. PostgreSQL parameters are positional, numbered starting from $1, and each placeholder must have a matching argument when the statement is executed. If your application skips a parameter, references a parameter number that doesn't exist, or forgets to bind values entirely, PostgreSQL will reject the query with this error. This typically indicates a mismatch between how your application generates SQL and how it supplies bind variables.
Typical symptoms
- Query execution fails immediately with "There is no parameter $1" or similar
- PREPARE statement works, but EXECUTE fails with missing parameter error
- Application code uses parameterized queries but parameters array is empty or incomplete
- PostgreSQL driver or ORM reports undefined_parameter SQLSTATE 42P02
- A query works in psql directly but fails when executed from application code
- Prepared statement compiled successfully but fails at runtime during binding
Common causes
- Missing or empty parameters array when calling the query function (e.g., passing [] instead of ["value"])
- Off-by-one error: using $2 when you only provided one parameter
- Parameter number mismatch: referencing $5 in the query but only providing 3 values
- Parameters array not passed at all to the database client
- Typo in parameter reference: using $A instead of $1 or similar incorrect syntax
- Driver or library not properly supporting parameterized queries
- Incorrect use of parameters in unsupported SQL contexts (identifiers, keywords, etc. instead of values)
How to fix "There is no parameter $N"
Open the SQL statement that's failing and count how many $1, $2, $3, etc. placeholders appear:
-- This query has 3 parameters: $1, $2, $3
SELECT * FROM users WHERE email = $1 AND status = $2 AND created > $3;Write down the number of placeholders (in this case, 3).
Find where your application calls this query and verify the parameters array has exactly the same number of values:
// Node.js with node-postgres - CORRECT
const res = await client.query(
'SELECT * FROM users WHERE email = $1 AND status = $2 AND created > $3',
['user@example.com', 'active', '2025-01-01']
);
// WRONG - missing parameters entirely
const res = await client.query(
'SELECT * FROM users WHERE email = $1 AND status = $2 AND created > $3'
);
// WRONG - only 2 values but query has 3 placeholders
const res = await client.query(
'SELECT * FROM users WHERE email = $1 AND status = $2 AND created > $3',
['user@example.com', 'active']
);Make sure the array length matches your placeholder count.
Parameters are matched positionally, so $1 gets the first array element, $2 gets the second, etc.:
// Query references $1 (email), $2 (status), $3 (date)
const query = 'SELECT * FROM users WHERE email = $1 AND status = $2 AND created > $3';
const params = ['alice@example.com', 'active', '2024-01-01'];
// $1 $2 $3
// CORRECT: array order matches placeholder order
await client.query(query, params);
// WRONG: parameters are in wrong order
await client.query(query, ['active', 'alice@example.com', '2024-01-01']);Reorder your parameters array to match the $1, $2, $3... sequence in the SQL.
Run your query directly in PostgreSQL to see if it works:
psql -h localhost -U postgres -d mydb -c "SELECT * FROM users WHERE email = $1"This will fail with the same error (no $1 provided). Now try with a value:
psql -h localhost -U postgres -d mydb -c "PREPARE stmt AS SELECT * FROM users WHERE email = $1; EXECUTE stmt('user@example.com');"This should work. If it does, the problem is in your application's parameter binding.
Different libraries use different placeholders:
// node-postgres uses $1, $2, $3
client.query('SELECT * FROM users WHERE id = $1', [123]);
// Some ORMs auto-convert ? to $N
// TypeORM, Sequelize, Knex may handle this differently
// Prisma uses different syntax entirely (no $N)
await prisma.users.findUnique({ where: { id: 123 } });
// Raw queries in Sequelize:
sequelize.query('SELECT * FROM users WHERE id = $1', {
bind: [123],
type: QueryTypes.SELECT
});Verify your library's exact syntax and parameter binding method, then apply the correct pattern.
Most database drivers allow query logging. Enable it to see exactly what SQL and parameters are being sent:
// node-postgres
const client = new Client({
...config,
log: (...args) => console.log('QUERY:', args)
});
// Or use environment variable for logging
process.env.NODE_DEBUG = 'pg';Run the failing query and compare the logged SQL parameters against the query string to spot mismatches.
Advanced notes
PostgreSQL parameter placeholders ($1, $2, etc.) are only valid for values, not for identifiers (table/column names) or SQL keywords. If you need parameterized table names, use dynamic SQL construction with proper escaping via pg_quote_ident() or your driver's identifier escaping function, but keep data values in the parameters array. Some drivers or ORMs automatically convert "?" placeholders to $1, $2, so understand your tool's conventions. In prepared statements created with PREPARE, parameters must be provided in the exact same order and count every time EXECUTE is called; mixing parameter counts is a common error when reusing prepared statements across different code paths.
Frequently asked questions
- What does "There is no parameter $N" mean?
- ) that has no corresponding value supplied. PostgreSQL parameters are positional, numbered starting from $1, and each placeholder must have a matching argument when the statement is executed. If your application skips a parameter, references a parameter number that doesn't exist, or forgets to bind values entirely, PostgreSQL will reject the query with this error.
- How do I fix "There is no parameter $N"?
- This error occurs when your parameterized SQL query references a placeholder like $1 or $2, but the corresponding parameter value was not provided when executing the statement. This is typically a binding mismatch between your application code and the prepared statement.
- What causes "There is no parameter $N"?
- Missing or empty parameters array when calling the query function (e.g., passing [] instead of ["value"]) Off-by-one error: using $2 when you only provided one parameter Parameter number mismatch: referencing $5 in the query but only providing 3 values
- Is the "There is no parameter $N" error serious?
- It is a medium-severity error โ more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- ๐PostgreSQL Official Documentation
- ๐postgresql.org - errcodes appendix(Official Docs)
- ๐postgresql.org - sql prepare(Official Docs)
- ๐postgresql.org - protocol prepared stmts(Official Docs)
- ๐pganalyze.com - U132(Official Docs)
- ๐
- ๐codecademy.com - positional parameters(Official Docs)
- ๐