How to fix 22014: invalid_argument_for_ntile_function in PostgreSQL
The NTILE() window function requires a positive integer argument representing the number of buckets. Error 22014 occurs when you pass an invalid argument type or value, such as zero, negative numbers, or non-integer types.
Quick fix
Fixes 22014
-- Incorrect: using 0 or negative numbers
SELECT ntile(0) OVER (ORDER BY id) FROM users; -- ERROR 22014
SELECT ntile(-4) OVER (ORDER BY id) FROM users; -- ERROR 22014
-- Correct: using positive integers
SELECT ntile(4) OVER (ORDER BY id) FROM users; -- OK
SELECT ntile(1) OVER (ORDER BY id) FROM users; -- OK- Verify your NTILE argument is a positive integer
- Check your data types and use explicit casting if needed
- Handle potential NULL values
- Test with a working example
-- Incorrect: using 0 or negative numbersSELECT ntile(0) OVER (ORDER BY id) FROM users; -- ERROR 22014SELECT ntile(-4) OVER (ORDER BY id) FROM users; -- ERROR 22014-- Correct: using positive integersSELECT ntile(4) OVER (ORDER BY id) FROM users; -- OKSELECT ntile(1) OVER (ORDER BY id) FROM users; -- OK22014: invalid_argument_for_ntile_function
What this error means
The NTILE() function divides ordered rows into ranked groups (buckets) and assigns each row a bucket number. The "invalid argument for ntile function" error occurs when the required buckets parameter violates PostgreSQL's strict requirements: it must be a positive integer greater than 0, and cannot be NULL or of an incompatible data type. This is a runtime validation error that happens when the function receives an argument that doesn't meet these specifications.
Typical symptoms
- Query execution fails with error code 22014 when using NTILE()
- Function works in some cases but fails with certain parameter values
- Getting this error when using calculated expressions or variables as the NTILE argument
- Window function queries abort before returning any results
Common causes
- Passing zero or negative number to NTILE() (must be >= 1)
- Passing a non-integer data type like float, string, or other type
- Using a NULL value or expression that evaluates to NULL
- Passing a value from a column with incompatible data type without explicit casting
- Using string literals instead of numeric literals
How to fix "22014: invalid_argument_for_ntile_function"
Check that you're passing a value greater than 0. The NTILE() function requires buckets to be at least 1.
-- Incorrect: using 0 or negative numbers
SELECT ntile(0) OVER (ORDER BY id) FROM users; -- ERROR 22014
SELECT ntile(-4) OVER (ORDER BY id) FROM users; -- ERROR 22014
-- Correct: using positive integers
SELECT ntile(4) OVER (ORDER BY id) FROM users; -- OK
SELECT ntile(1) OVER (ORDER BY id) FROM users; -- OKEnsure the argument is an integer type. If you're using a column or expression, cast it to integer explicitly.
-- Incorrect: passing a string literal
SELECT ntile('4') OVER (ORDER BY id) FROM users; -- ERROR 22014
-- Incorrect: using float
SELECT ntile(4.5) OVER (ORDER BY id) FROM users; -- ERROR 22014
-- Correct: using integer literal
SELECT ntile(4) OVER (ORDER BY id) FROM users;
-- Correct: casting column value to integer
SELECT ntile(CAST(bucket_count AS INTEGER)) OVER (ORDER BY id) FROM users;
-- Correct: using :: operator for casting
SELECT ntile(bucket_count::integer) OVER (ORDER BY id) FROM users;If your argument comes from a column or expression, use COALESCE() to provide a default value, as NULL arguments will trigger error 22014.
-- Incorrect: column might contain NULL
SELECT ntile(bucket_count) OVER (ORDER BY id) FROM users; -- ERROR if NULL
-- Correct: provide default value for NULL
SELECT ntile(COALESCE(bucket_count, 4)) OVER (ORDER BY id) FROM users;
-- Correct: use NULLIF to ensure positive values
SELECT ntile(NULLIF(bucket_count, 0)) OVER (ORDER BY id) FROM users;Start with a simple, hardcoded example to verify your syntax is correct, then gradually add complexity.
-- Working baseline example
SELECT
id,
name,
salary,
ntile(4) OVER (ORDER BY salary) AS salary_quartile
FROM employees;
-- Verify you can see the bucket assignments (1, 2, 3, or 4)
-- Then adjust the number based on your requirementsAdvanced notes
The NTILE() function is a window function that requires strict parameter validation. Error 22014 specifically indicates type or value validation failure at the database level. When using dynamic values (from parameters, columns, or expressions), always ensure explicit integer conversion and NULL handling. Some common patterns: use CASE statements to conditionally set bucket counts, use GREATEST() to ensure minimum value of 1, and use FILTER clauses on window functions for complex partitioning logic. The bucket count applies per partition when using PARTITION BY, so ensure your partition logic aligns with your intended distribution strategy.
Frequently asked questions
- What does "22014" mean?
- The NTILE() function divides ordered rows into ranked groups (buckets) and assigns each row a bucket number. The "invalid argument for ntile function" error occurs when the required buckets parameter violates PostgreSQL's strict requirements: it must be a positive integer greater than 0, and cannot be NULL or of an incompatible data type. This is a runtime validation error that happens when the function receives an argument that doesn't meet these specifications.
- How do I fix "22014"?
- The NTILE() window function requires a positive integer argument representing the number of buckets. Error 22014 occurs when you pass an invalid argument type or value, such as zero, negative numbers, or non-integer types.
- What causes "22014"?
- Passing zero or negative number to NTILE() (must be >= 1) Passing a non-integer data type like float, string, or other type Using a NULL value or expression that evaluates to NULL
- Is the "22014" 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 18 - Window Functions(Official Docs)