TheAlgorithms/Python · error · ValueError

'time_value' must be a non-negative number.

Error message

'time_value' must be a non-negative number.

What it means

Raised by convert_time() in conversions/time_conversions.py when time_value is not an int/float or is negative. Note the isinstance check accepts bool (subclass of int) and rejects numeric strings like '60'. Units are validated separately in a later check.

Source

Thrown at conversions/time_conversions.py:64

    Traceback (most recent call last):
        ...
    ValueError: 'time_value' must be a non-negative number.
    >>> convert_time([0, 1, 2], "weeks", "days")
    Traceback (most recent call last):
        ...
    ValueError: 'time_value' must be a non-negative number.
    >>> convert_time(1, "cool", "century")  # doctest: +ELLIPSIS
    Traceback (most recent call last):
        ...
    ValueError: Invalid unit cool is not in seconds, minutes, hours, days, weeks, ...
    >>> convert_time(1, "seconds", "hot")  # doctest: +ELLIPSIS
    Traceback (most recent call last):
        ...
    ValueError: Invalid unit hot is not in seconds, minutes, hours, days, weeks, ...
    """
    if not isinstance(time_value, (int, float)) or time_value < 0:
        msg = "'time_value' must be a non-negative number."
        raise ValueError(msg)

    unit_from = unit_from.lower()
    unit_to = unit_to.lower()
    if unit_from not in time_chart or unit_to not in time_chart:
        invalid_unit = unit_from if unit_from not in time_chart else unit_to
        msg = f"Invalid unit {invalid_unit} is not in {', '.join(time_chart)}."
        raise ValueError(msg)

    return round(
        time_value * time_chart[unit_from] * time_chart_inverse[unit_to],
        3,
    )


if __name__ == "__main__":
    import doctest

    doctest.testmod()

View on GitHub (pinned to f5988cc097)

Solutions

  1. Cast numeric strings: convert_time(float(user_input), ...).
  2. Use abs() or validate ordering if negative deltas are computation-order artifacts.
  3. Reject NaN explicitly: if math.isnan(v): raise before calling.

Example fix

# before
convert_time('-60', 'seconds', 'minutes')  # ValueError: 'time_value' must be a non-negative number.

# after
value = float('-60')
if value < 0:
    raise ValueError('duration cannot be negative')
convert_time(value, 'seconds', 'minutes')
Defensive patterns

Strategy: validation

Validate before calling

import math

if not isinstance(time_value, (int, float)) or isinstance(time_value, bool):
    time_value = float(time_value)
if math.isnan(time_value) or time_value < 0:
    raise ValueError('duration must be a non-negative number')
convert_time(time_value, unit_from, unit_to)

Type guard

def is_valid_duration(v: object) -> bool:
    return (
        isinstance(v, (int, float))
        and not isinstance(v, bool)
        and not (isinstance(v, float) and math.isnan(v))
        and v >= 0
    )

Try / catch

try:
    convert_time(v, f, t)
except ValueError as e:
    if 'non-negative' in str(e):
        v = abs(float(v))
        result = convert_time(v, f, t)
    else:
        raise

Prevention

When it happens

Trigger: Calling convert_time(-1, 'seconds', 'minutes'), convert_time('60', 'seconds', 'minutes') (string), or passing None from an optional field.

Common situations: Timestamps/deltas computed as date differences that went negative due to ordering; CLI/query params arriving as strings and not cast; NaN from empty pandas cells (float NaN passes isinstance but NaN < 0 is False — NaN slips through, so sanitize it yourself).

Related errors


AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14). Data as JSON: /api/errors/54839dc32c4a1b8c. Report an issue: GitHub.