{"record":{"id":"ec329728f560c3af","repo":"TheAlgorithms/Python","slug":"position-must-be-non-negative","errorCode":null,"errorMessage":"Position must be non-negative","messagePattern":"Position must be non-negative","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"data_structures/linked_list/__init__.py","lineNumber":62,"sourceCode":"        3 --> 2 --> 4 --> 1\n\n        # Test adding to a negative position\n        >>> linked_list.add(5, -3)\n        Traceback (most recent call last):\n            ...\n        ValueError: Position must be non-negative\n\n        # Test adding to an out-of-bounds position\n        >>> linked_list.add(5,7)\n        Traceback (most recent call last):\n            ...\n        ValueError: Out of bounds\n        >>> linked_list.add(5, 4)\n        >>> print(linked_list)\n        3 --> 2 --> 4 --> 1 --> 5\n        \"\"\"\n        if position < 0:\n            raise ValueError(\"Position must be non-negative\")\n\n        if position == 0 or self.head is None:\n            new_node = Node(item, self.head)\n            self.head = new_node\n        else:\n            current = self.head\n            for _ in range(position - 1):\n                current = current.next\n                if current is None:\n                    raise ValueError(\"Out of bounds\")\n            new_node = Node(item, current.next)\n            current.next = new_node\n        self.size += 1\n\n    def remove(self) -> Any:\n        # Switched 'self.is_empty()' to 'self.head is None'\n        # because mypy was considering the possibility that 'self.head'\n        # can be None in below else part and giving error","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/data_structures/linked_list/__init__.py#L44-L80","documentation":"Raised by LinkedList.add(item, position) (data_structures/linked_list/__init__.py) when position < 0. Positions are 0-indexed insertion slots; negative indices are not supported (unlike Python lists), so the method raises ValueError('Position must be non-negative') before walking the list. The sibling guard at the same call site raises 'Out of bounds' when the walk runs past the tail.","triggerScenarios":"linked_list.add(item, -1) attempting list-style negative indexing; position computed as `i - len(...)` which goes negative at i == 0; user-supplied index parsed without validation.","commonSituations":"Porting list code that uses [-1] semantics; index arithmetic that assumes a non-empty list; CLI/form input for a position not validated as >= 0.","solutions":["Validate/clamp the index at the caller: `pos = max(0, pos)` or reject negatives with your own message","Fix index math — compute positions forward from the head, not as negative offsets from the tail","If you need end-insertion, use the size: add(item, linked_list.size) appends at the tail"],"exampleFix":"# before\nlinked_list.add(5, -1)  # ValueError\n\n# after\nlinked_list.add(5, linked_list.size)  # append at end","handlingStrategy":"validation","validationCode":"position = max(0, position)\nlinked_list.add(item, position)","typeGuard":"def is_valid_position(pos: object, size: int) -> bool:\n    return isinstance(pos, int) and 0 <= pos <= size","tryCatchPattern":"try:\n    linked_list.add(item, position)\nexcept ValueError as e:\n    if 'non-negative' not in str(e):\n        raise\n    linked_list.add(item, 0)  # fall back to head insert","preventionTips":["No negative indexing here — convert -1 style offsets to size-based positions","Validate user-supplied positions as int >= 0 at the input boundary","Use add(item, linked_list.size) to append"],"tags":["linked-list","negative-index","insert","validation"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}