{"record":{"id":"e9b6fd1b6482216f","repo":"python/cpython","slug":"unconverted-data-remains-s","errorCode":null,"errorMessage":"unconverted data remains: %s","messagePattern":"unconverted data remains: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Lib/_strptime.py","lineNumber":587,"sourceCode":"                raise ValueError(\"'%s' is a bad directive in format '%s'\" %\n                                    (bad_directive, format)) from None\n            _regex_cache[format] = format_regex\n    found = format_regex.match(data_string)\n    if not found:\n        raise ValueError(\"time data %r does not match format %r\" %\n                         (data_string, format))\n    if len(data_string) != found.end():\n        rest = data_string[found.end():]\n        # Specific check for '%:z' directive\n        if (\n            \"colon_z\" in found.re.groupindex\n            and found.group(\"colon_z\") is not None\n            and rest[0] != \":\"\n        ):\n            raise ValueError(\n                f\"Missing colon in %:z before '{rest}', got '{data_string}'\"\n            )\n        raise ValueError(\"unconverted data remains: %s\" % rest)\n\n    iso_year = year = None\n    month = day = 1\n    hour = minute = second = fraction = 0\n    tz = -1\n    gmtoff = None\n    gmtoff_fraction = 0\n    iso_week = week_of_year = None\n    week_of_year_start = None\n    # weekday and julian defaulted to None so as to signal need to calculate\n    # values\n    weekday = julian = None\n    found_dict = found.groupdict()\n    if locale_time.LC_alt_digits:\n        def parse_int(s):\n            try:\n                return locale_time.LC_alt_digits.index(s)\n            except ValueError:","sourceCodeStart":569,"sourceCodeEnd":605,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_strptime.py#L569-L605","documentation":"The format regex matched a prefix of the input but data_string is longer than what the format covers — len(data_string) != found.end() with no %:z colon case. The ValueError reports the leftover suffix (rest = data_string[found.end():]).","triggerScenarios":"datetime.strptime('2020-01-01 12:00', '%Y-%m-%d') — the time part ' 12:00' remains; or a trailing timezone name, milliseconds, or newline not covered by the format.","commonSituations":"Log lines with extra trailing fields; input with trailing '\\n' from file.readline(); forgetting %H:%M:%S or %f/%Z directives for the tail of the string.","solutions":["Add directives for the remaining text (%H:%M:%S, %f, %Z, %z) or matching literals","Strip/slice the input to exactly what the format covers: data.split(' ')[0]","Use dateutil.parser or fromisoformat for variable-length inputs"],"exampleFix":"# before\n>>> datetime.strptime('2020-01-01 12:00', '%Y-%m-%d')\nValueError: unconverted data remains:  12:00\n\n# after\n>>> datetime.strptime('2020-01-01 12:00', '%Y-%m-%d %H:%M')\ndatetime.datetime(2020, 1, 1, 12, 0)","handlingStrategy":"fallback","validationCode":"from datetime import datetime\n\ndef parse_prefix(s: str, fmt: str):\n    for end in range(len(s), 0, -1):\n        try:\n            return datetime.strptime(s[:end], fmt)\n        except ValueError:\n            continue\n    raise ValueError(f'no prefix of {s!r} matches {fmt!r}')","typeGuard":null,"tryCatchPattern":"try:\n    dt = datetime.strptime(line.strip(), fmt)\nexcept ValueError as e:\n    if str(e).startswith('unconverted data remains'):\n        dt = datetime.strptime(line.strip()[:len_covered(fmt)], fmt)\n    else:\n        raise","preventionTips":["Cover every field of the input in the format (times, fraction, zone)","Strip trailing newlines/whitespace from file-read lines before parsing","Log the reported 'rest' substring — it tells you exactly which directive is missing"],"tags":["strptime","datetime","parsing","trailing-data","cpython"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}