{"record":{"id":"07b536a8541735ae","repo":"donnemartin/interactive-coding-challenges","slug":"num-pairs-cannot-be-0","errorCode":null,"errorMessage":"num_pairs cannot be < 0","messagePattern":"num_pairs cannot be < 0","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"recursion_dynamic/n_pairs_parentheses/n_pairs_parentheses_solution.ipynb","lineNumber":110,"sourceCode":"   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Parentheses(object):\\n\",\n    \"\\n\",\n    \"    def find_pair(self, num_pairs):\\n\",\n    \"        if num_pairs is None:\\n\",\n    \"            raise TypeError('num_pairs cannot be None')\\n\",\n    \"        if num_pairs < 0:\\n\",\n    \"            raise ValueError('num_pairs cannot be < 0')\\n\",\n    \"        if not num_pairs:\\n\",\n    \"            return []\\n\",\n    \"        results = []\\n\",\n    \"        curr_results = []\\n\",\n    \"        self._find_pair(num_pairs, num_pairs, curr_results, results)\\n\",\n    \"        return results\\n\",\n    \"\\n\",\n    \"    def _find_pair(self, nleft, nright, curr_results, results):\\n\",\n    \"        if nleft == 0 and nright == 0:\\n\",\n    \"            results.append(''.join(curr_results))\\n\",\n    \"        else:\\n\",\n    \"            if nleft >= 0:\\n\",\n    \"                self._find_pair(nleft-1, nright, curr_results+['('], results)\\n\",\n    \"            if nright > nleft:\\n\",\n    \"                self._find_pair(nleft, nright-1, curr_results+[')'], results)\"\n   ]\n  },\n  {","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/donnemartin/interactive-coding-challenges/blob/358f2cc60426d5c4c3d7d580910eec9a7b393fa9/recursion_dynamic/n_pairs_parentheses/n_pairs_parentheses_solution.ipynb#L92-L128","documentation":"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.","triggerScenarios":"Calling find_pair(-1) or any num_pairs < 0. Zero is valid and returns []; None raises the TypeError instead.","commonSituations":"Arithmetic on user input producing a negative count (e.g. n - offset); off-by-one loops passing -1; parsing '-3' from unvalidated input.","solutions":["Clamp or reject negative input before calling: max(0, n) or raise your own 400 error","Fix the upstream computation that produced the negative count","Validate input range at the API boundary (0 <= n <= reasonable cap)"],"exampleFix":"// before\nresults = p.find_pair(user_n - offset)\n// after\nresults = p.find_pair(max(0, user_n - offset))","handlingStrategy":"validation","validationCode":"if num_pairs is None or num_pairs < 0:\n    raise ValueError('num_pairs must be a non-negative integer')\np.find_pair(num_pairs)","typeGuard":"def is_nonneg_int(x):\n    return isinstance(x, int) and not isinstance(x, bool) and x >= 0","tryCatchPattern":"try:\n    p.find_pair(n)\nexcept ValueError as e:\n    return bad_request(str(e))","preventionTips":["Clamp computed counts with max(0, n)","Validate numeric ranges at API boundaries"],"tags":["python","valueerror","recursion","backtracking","input-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"358f2cc60426d5c4c3d7d580910eec9a7b393fa9","analyzedAt":"2026-08-28T10:16:54.480Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}