TheAlgorithms/Python · error · ValueError
Limit for the Catalan sequence must be ≥ 0
Error message
Limit for the Catalan sequence must be ≥ 0
What it means
Raised by catalan_numbers(upper_limit) when upper_limit is negative. The function builds a list of length upper_limit + 1, so any negative limit other than the guard would create an empty or invalid list; a negative index would crash later. ValueError is thrown immediately with a clear 'must be >= 0' message (documented in the doctest for -1).
Source
Thrown at dynamic_programming/catalan_numbers.py:43
* [1] https://brilliant.org/wiki/catalan-numbers/
* [2] https://en.wikipedia.org/wiki/Catalan_number
"""
def catalan_numbers(upper_limit: int) -> "list[int]":
"""
Return a list of the Catalan number sequence from 0 through `upper_limit`.
>>> catalan_numbers(5)
[1, 1, 2, 5, 14, 42]
>>> catalan_numbers(2)
[1, 1, 2]
>>> catalan_numbers(-1)
Traceback (most recent call last):
ValueError: Limit for the Catalan sequence must be ≥ 0
"""
if upper_limit < 0:
raise ValueError("Limit for the Catalan sequence must be ≥ 0")
catalan_list = [0] * (upper_limit + 1)
# Base case: C(0) = C(1) = 1
catalan_list[0] = 1
if upper_limit > 0:
catalan_list[1] = 1
# Recurrence relation: C(i) = sum(C(j).C(i-j-1)), from j = 0 to i
for i in range(2, upper_limit + 1):
for j in range(i):
catalan_list[i] += catalan_list[j] * catalan_list[i - j - 1]
return catalan_list
if __name__ == "__main__":
print("\n********* Catalan Numbers Using Dynamic Programming ************\n")View on GitHub (pinned to f5988cc097)
Solutions
- Check the bound before calling: n = max(0, n) only if clamping is acceptable, otherwise surface the error to the caller.
- Fix the source of the negative value — usually an empty input list or an off-by-one in limit computation.
- Validate user-supplied limits at the CLI/config boundary with int(x); x >= 0 checks.
Example fix
# before
limit = len(values) - 1 # -1 when values is empty
cats = catalan_numbers(limit)
# after
if values:
cats = catalan_numbers(len(values) - 1)
else:
cats = [] Defensive patterns
Strategy: validation
Validate before calling
upper_limit = int(upper_limit)
if upper_limit < 0:
raise ValueError('upper_limit must be >= 0')
cats = catalan_numbers(upper_limit) Type guard
def is_non_negative_int(value: object) -> bool:
return isinstance(value, int) and value >= 0 Try / catch
try:
cats = catalan_numbers(limit)
except ValueError as exc:
if 'must be' in str(exc):
cats = [] # or re-raise with domain context
else:
raise Prevention
- Never derive sequence limits from len(collection) - 1 without handling empty collections.
- Validate numeric bounds at the CLI/config boundary.
- Fuzz test numeric helpers with -1, 0, and 1 to catch bound bugs early.
When it happens
Trigger: catalan_numbers(-1) or any negative integer argument, e.g. when upper_limit comes from user input or len(data) - 1 on an empty dataset. Floats like -0.5 also compare negative and raise.
Common situations: Computing a range bound from an empty collection (len([]) - 1 == -1); CLI arguments parsed without validation; off-by-one when converting an inclusive/exclusive limit.
Related errors
- Negative arguments are not supported
- the value of input must be a natural number
- Number should not be negative.
- iterations must be defined as integers
- starting number must be and integer
AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14).
Data as JSON: /api/errors/8e859f257272446d.
Report an issue: GitHub.