{"record":{"id":"424ef39218fe03ee","repo":"python/cpython","slug":"argument-must-be-a-str","errorCode":null,"errorMessage":"Argument must be a str","messagePattern":"Argument must be a str","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"Lib/_pydatetime.py","lineNumber":1054,"sourceCode":"        t = _time.time()\n        return cls.fromtimestamp(t)\n\n    @classmethod\n    def fromordinal(cls, n):\n        \"\"\"Construct a date from a proleptic Gregorian ordinal.\n\n        January 1 of year 1 is day 1.  Only the year, month and day are\n        non-zero in the result.\n        \"\"\"\n        y, m, d = _ord2ymd(n)\n        return cls(y, m, d)\n\n    @classmethod\n    def fromisoformat(cls, date_string):\n        \"\"\"Construct a date from a string in ISO 8601 format.\"\"\"\n\n        if not isinstance(date_string, str):\n            raise TypeError('Argument must be a str')\n\n        if not date_string.isascii():\n            raise ValueError('Argument must be an ASCII str')\n\n        if len(date_string) not in (7, 8, 10):\n            raise ValueError(f'Invalid isoformat string: {date_string!r}')\n\n        try:\n            return cls(*_parse_isoformat_date(date_string))\n        except Exception:\n            raise ValueError(f'Invalid isoformat string: {date_string!r}')\n\n    @classmethod\n    def fromisocalendar(cls, year, week, day):\n        \"\"\"Construct a date from the ISO year, week number and weekday.\n\n        This is the inverse of the date.isocalendar() function\"\"\"\n        return cls(*_isoweek_to_gregorian(year, week, day))","sourceCodeStart":1036,"sourceCodeEnd":1072,"githubUrl":"https://github.com/python/cpython/blob/bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6/Lib/_pydatetime.py#L1036-L1072","documentation":"Raised by date.fromisoformat() when the argument is not a str instance. The parser handles only the ISO 8601 date text format; bytes, bytearrays, or other objects must be decoded first. This is a deliberate TypeError separating 'wrong type' from 'wrong format' (which raises ValueError).","triggerScenarios":"date.fromisoformat(b'2024-01-01'); passing a pathlib-derived bytes value or a value from a JSON parser that yields non-str; fromisoformat(None).","commonSituations":"Feeding bytes read from sockets/files or from Redis/kafka consumers directly; mixed str/bytes pipelines after a Python 2→3 migration; passing user input that arrived as bytes from a web framework.","solutions":["Decode first: date.fromisoformat(raw.decode('utf-8'))","Check isinstance(s, str) at the ingestion boundary","For full ISO 8601 including 'Z' and offsets on datetimes, use datetime.fromisoformat (3.11+) or dateutil"],"exampleFix":"# before\nd = date.fromisoformat(body['date'])  # bytes from request\n# after\nd = date.fromisoformat(body['date'].decode('utf-8'))","handlingStrategy":"type-guard","validationCode":"if not isinstance(s, str):\n    s = s.decode('utf-8') if isinstance(s, (bytes, bytearray)) else str(s)\nd = date.fromisoformat(s)","typeGuard":"def is_iso_str(v) -> bool:\n    return isinstance(v, str)","tryCatchPattern":null,"preventionTips":["Decode bytes to str at the ingestion boundary (sockets, Redis, files)","Type-check user input before fromisoformat to give clearer errors than the library's"],"tags":["datetime","typeerror","iso-8601","parsing"],"backgroundTag":null,"analyzedSha":"bc6749cc3b5ae4a5e88a6cc2d5b3bebbe354eae6","analyzedAt":"2026-08-14T22:01:13.976Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}