Skip to content

JSON deserialization does not handle OverflowError #480

Description

Trying to deserialize certain misformatted strings result in an uncaught OverflowError exception instead of passing through the string unchanged. In particular, trying to deserialize a timedelta string such as "50001140846:00021" results in the following:

Traceback (most recent call last):
  File "lib\site-packages\kiota_abstractions\date_utils.py", line 66, in parse_timedelta_string
    return parse_timedelta_from_iso_format(text)
  File "lib\site-packages\kiota_abstractions\date_utils.py", line 34, in parse_timedelta_from_iso_format
    raise ValueError(f"Invalid ISO8601 duration string: {text}")
ValueError: Invalid ISO8601 duration string: 50001140846:00021

During handling of the above exception, another exception occurred:
Traceback (most recent call last):
[...]
  File "lib\site-packages\kiota_serialization_json\json_parse_node.py", line 335, in try_get_anything
    return parse_timedelta_string(value)
  File "lib\site-packages\kiota_abstractions\date_utils.py", line 76, in parse_timedelta_string
    return timedelta(hours=hours, minutes=minutes, seconds=seconds)
OverflowError: days=2083380868; must have magnitude <= 999999999

The issue is that JsonParseNode.try_get_anything() only handles ValueError exceptions instead of also handling OverflowError. Changing this line to catch both ValueError and OverflowError allows deserialization to be successful:

Most likely the other catch handlers in try_get_anything() should be updated as well.

Activity

  1. moved this to Needs Triage 🔍 in Kiotaon May 13, 2025
  2. HardMax71 commented on Oct 3, 2026

    @HardMax71
    Contributor

    Still reproduces on 1.14.1 and on main (ce04532), just not on the exact path from the report anymore.

    The additional_data path was fixed by #664, released in serialization-json 1.11.8. JsonParseNode.try_get_anything no longer tries untyped strings as durations, so "50001140846:00021" stays a string. The root cause is still there though. parse_timedelta_string builds a timedelta without guarding against overflow (date_utils.py#L51, #L76), and the callers only catch ValueError. So the same OverflowError still gets out of three other places:

    • a typed timedelta property in JSON (json_parse_node.py#L262-L270). "not-a-duration" gives None there, but these values crash deserialization of the whole response
    • FormParseNode.try_get_anything (form_parse_node.py#L277-L279), which still has the old parser chain, so it's the reported bug again in the form package
    • JsonSerializationWriter.write_timedelta_value with a string (json_serialization_writer.py#L144-L155), which leaks the raw OverflowError instead of its own "Invalid timedelta string value found"

    It isn't limited to the hh:mm:ss fallback either. "P1000000000D" is a valid ISO 8601 duration, just past timedelta.max.

    Repro, after pip install microsoft-kiota-serialization-json==1.14.1 microsoft-kiota-serialization-form==1.14.1:

    from kiota_serialization_form.form_parse_node import FormParseNode
    from kiota_serialization_json.json_parse_node import JsonParseNode
    from kiota_serialization_json.json_serialization_writer import JsonSerializationWriter
    
    for value in ("50001140846:00021", "P1000000000D", "not-a-duration"):
        print(repr(value))
        for label, call in (
            ("json try_get_anything", lambda: JsonParseNode(value).try_get_anything(value)),
            ("json get_timedelta_value", lambda: JsonParseNode(value).get_timedelta_value()),
            ("form try_get_anything", lambda: FormParseNode(value).try_get_anything(value)),
            ("json write_timedelta_value", lambda: JsonSerializationWriter().write_timedelta_value("d", value)),
        ):
            try:
                print(f"  {label}: {call()!r}")
            except Exception as exc:
                print(f"  {label}: {type(exc).__name__}: {exc}")

    Output on 1.14.1, and main gives the same. On 1.9.3 the json try_get_anything lines raise too, with the same traceback as in the report.

    '50001140846:00021'
      json try_get_anything: '50001140846:00021'
      json get_timedelta_value: OverflowError: days=2083380868; must have magnitude <= 999999999
      form try_get_anything: OverflowError: days=2083380868; must have magnitude <= 999999999
      json write_timedelta_value: OverflowError: days=2083380868; must have magnitude <= 999999999
    'P1000000000D'
      json try_get_anything: 'P1000000000D'
      json get_timedelta_value: OverflowError: days=1000000000; must have magnitude <= 999999999
      form try_get_anything: OverflowError: days=1000000000; must have magnitude <= 999999999
      json write_timedelta_value: OverflowError: days=1000000000; must have magnitude <= 999999999
    'not-a-duration'
      json try_get_anything: 'not-a-duration'
      json get_timedelta_value: None
      form try_get_anything: 'not-a-duration'
      json write_timedelta_value: ValueError: Invalid timedelta string value found for property d
    

    The smallest fix is in date_utils: raise ValueError instead of OverflowError in parse_timedelta_from_iso_format and in the hh:mm:ss branch of parse_timedelta_string. The json and form callers already handle ValueError, so that covers all three at once. I can send a PR for it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    • Status
      Done ✔️

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions