donnemartin/interactive-coding-challenges · error · ValueError

num_pairs cannot be < 0

Error message

num_pairs cannot be < 0

What it means

Raised by Parentheses.find_pair when num_pairs is negative. It is a ValueError (not TypeError), thrown after the None check, because generating n pairs of parentheses is only defined for n >= 0; the recursive helper decrements counts and would never terminate correctly with a negative start.

Source

Thrown at recursion_dynamic/n_pairs_parentheses/n_pairs_parentheses_solution.ipynb:110

   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Code"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Parentheses(object):\n",
    "\n",
    "    def find_pair(self, num_pairs):\n",
    "        if num_pairs is None:\n",
    "            raise TypeError('num_pairs cannot be None')\n",
    "        if num_pairs < 0:\n",
    "            raise ValueError('num_pairs cannot be < 0')\n",
    "        if not num_pairs:\n",
    "            return []\n",
    "        results = []\n",
    "        curr_results = []\n",
    "        self._find_pair(num_pairs, num_pairs, curr_results, results)\n",
    "        return results\n",
    "\n",
    "    def _find_pair(self, nleft, nright, curr_results, results):\n",
    "        if nleft == 0 and nright == 0:\n",
    "            results.append(''.join(curr_results))\n",
    "        else:\n",
    "            if nleft >= 0:\n",
    "                self._find_pair(nleft-1, nright, curr_results+['('], results)\n",
    "            if nright > nleft:\n",
    "                self._find_pair(nleft, nright-1, curr_results+[')'], results)"
   ]
  },
  {

View on GitHub (pinned to 358f2cc604)

Solutions

  1. Clamp or reject negative input before calling: max(0, n) or raise your own 400 error
  2. Fix the upstream computation that produced the negative count
  3. Validate input range at the API boundary (0 <= n <= reasonable cap)

Example fix

// before
results = p.find_pair(user_n - offset)
// after
results = p.find_pair(max(0, user_n - offset))
Defensive patterns

Strategy: validation

Validate before calling

if num_pairs is None or num_pairs < 0:
    raise ValueError('num_pairs must be a non-negative integer')
p.find_pair(num_pairs)

Type guard

def is_nonneg_int(x):
    return isinstance(x, int) and not isinstance(x, bool) and x >= 0

Try / catch

try:
    p.find_pair(n)
except ValueError as e:
    return bad_request(str(e))

Prevention

When it happens

Trigger: Calling find_pair(-1) or any num_pairs < 0. Zero is valid and returns []; None raises the TypeError instead.

Common situations: Arithmetic on user input producing a negative count (e.g. n - offset); off-by-one loops passing -1; parsing '-3' from unvalidated input.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of donnemartin/interactive-coding-challenges@358f2cc604 (2026-08-28). Data as JSON: /api/errors/07b536a8541735ae. Report an issue: GitHub.