{"record":{"id":"c3930383e9521414","repo":"TheAlgorithms/Python","slug":"input-must-be-a-non-negative-integer-c39303","errorCode":null,"errorMessage":"Input must be a non-negative integer","messagePattern":"Input must be a non-negative integer","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"bit_manipulation/index_of_rightmost_set_bit.py","lineNumber":33,"sourceCode":"    2\n    >>> get_index_of_rightmost_set_bit(8)\n    3\n    >>> get_index_of_rightmost_set_bit(-18)\n    Traceback (most recent call last):\n        ...\n    ValueError: Input must be a non-negative integer\n    >>> get_index_of_rightmost_set_bit('test')\n    Traceback (most recent call last):\n        ...\n    ValueError: Input must be a non-negative integer\n    >>> get_index_of_rightmost_set_bit(1.25)\n    Traceback (most recent call last):\n        ...\n    ValueError: Input must be a non-negative integer\n    \"\"\"\n\n    if not isinstance(number, int) or number < 0:\n        raise ValueError(\"Input must be a non-negative integer\")\n\n    intermediate = number & ~(number - 1)\n    index = 0\n    while intermediate:\n        intermediate >>= 1\n        index += 1\n    return index - 1\n\n\nif __name__ == \"__main__\":\n    \"\"\"\n    Finding the index of rightmost set bit has some very peculiar use-cases,\n    especially in finding missing or/and repeating numbers in a list of\n    positive integers.\n    \"\"\"\n    import doctest\n\n    doctest.testmod(verbose=True)","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/bit_manipulation/index_of_rightmost_set_bit.py#L15-L51","documentation":"Raised by get_index_of_rightmost_set_bit when the input is not an int or is negative. The function isolates the lowest set bit with number & ~(number - 1) and shifts to find its index — integer-only logic — so both wrong types and negatives raise this single ValueError.","triggerScenarios":"Calling get_index_of_rightmost_set_bit('test'), get_index_of_rightmost_set_bit(1.25), or (-4). Note: input 0 is accepted but returns -1 because no bit is set.","commonSituations":"Feeding bitmask indices from string configs or float computations; passing 0 and misreading the -1 return as an index instead of handling it.","solutions":["Convert numeric inputs: get_index_of_rightmost_set_bit(int(value)).","Handle 0 explicitly before calling, since the function returns -1 rather than raising for it.","For positive ints, an O(1) alternative is (number & -number).bit_length() - 1."],"exampleFix":"# before\nget_index_of_rightmost_set_bit('test')  # ValueError\n\n# after\nget_index_of_rightmost_set_bit(int('40'))  # 3","handlingStrategy":"validation","validationCode":"if not isinstance(number, int) or number < 0:\n    raise ValueError(\"need a non-negative int\")\nif number == 0:\n    raise ValueError(\"0 has no set bit (function would return -1)\")","typeGuard":"def is_positive_int(n: object) -> bool:\n    return isinstance(n, int) and not isinstance(n, bool) and n > 0","tryCatchPattern":null,"preventionTips":["int() inputs from string configs before bit-index queries.","Special-case 0 before calling; the -1 return is easy to misuse.","Use (n & -n).bit_length() - 1 as an inline, guarded alternative."],"tags":["bit-manipulation","input-validation","type-validation","python"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}