{"record":{"id":"f39cd71b4b15fbeb","repo":"aio-libs/aiohttp","slug":"unsupported-type-for-last-modified-type-value","errorCode":null,"errorMessage":"Unsupported type for last_modified: {type(value).__name__}","messagePattern":"Unsupported type for last_modified: (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"aiohttp/web_response.py","lineNumber":279,"sourceCode":"        self, value: int | float | datetime.datetime | str | None\n    ) -> None:\n        if value is None:\n            self._headers.pop(hdrs.LAST_MODIFIED, None)\n        elif isinstance(value, (int, float)):\n            self._headers[hdrs.LAST_MODIFIED] = time.strftime(\n                \"%a, %d %b %Y %H:%M:%S GMT\", time.gmtime(math.ceil(value))\n            )\n        elif isinstance(value, datetime.datetime):\n            if value.microsecond:\n                value = value.replace(microsecond=0) + datetime.timedelta(seconds=1)\n            self._headers[hdrs.LAST_MODIFIED] = time.strftime(\n                \"%a, %d %b %Y %H:%M:%S GMT\", value.utctimetuple()\n            )\n        elif isinstance(value, str):\n            self._headers[hdrs.LAST_MODIFIED] = value\n        else:\n            msg = f\"Unsupported type for last_modified: {type(value).__name__}\"  # type: ignore[unreachable]\n            raise TypeError(msg)\n\n    @property\n    def etag(self) -> ETag | None:\n        quoted_value = self._headers.get(hdrs.ETAG)\n        if not quoted_value:\n            return None\n        elif quoted_value == ETAG_ANY:\n            return ETag(value=ETAG_ANY)\n        match = QUOTED_ETAG_RE.fullmatch(quoted_value)\n        if not match:\n            return None\n        is_weak, value = match.group(1, 2)\n        return ETag(\n            is_weak=bool(is_weak),\n            value=value,\n        )\n\n    @etag.setter","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/d041d4d0fd48c3f0832084d33be16cf1c4835f85/aiohttp/web_response.py#L261-L297","documentation":"Raised by the last_modified setter when the assigned value is not None, int, float, datetime.datetime, or str. The setter formats the header into an RFC 7231 IMF-fixdate string and only knows how to convert those five input shapes. Any other type (e.g. a date object, a pandas Timestamp, a tuple) is rejected as a programming error rather than silently mis-formatted.","triggerScenarios":"Assigning `resp.last_modified = datetime.date.today()` (date, not datetime), a `pandas.Timestamp`, a `tuple`, a `time.struct_time`, or any custom object to the last_modified property. Passing such a value through a helper that forwards to the setter.","commonSituations":"Using `datetime.date` (no time component) instead of `datetime.datetime`; using ORM/model fields declared as `DateField` that return date objects; feeding a numpy/pandas timestamp from analytics code into a caching middleware that sets Last-Modified.","solutions":["Convert date to datetime before assigning: `resp.last_modified = datetime.datetime.combine(my_date, datetime.time.min)`.","Convert to a Unix timestamp (int/float): `resp.last_modified = my_date.timestamp()` or `calendar.timegm(my_date.timetuple())`.","Format as an RFC 7231 string yourself and assign the str form.","If the model field is a pandas.Timestamp, call `.to_pydatetime()` to get a stdlib datetime."],"exampleFix":"// before\nresp.last_modified = record.updated_at.date()  # date -> TypeError\n\n// after\nimport datetime\nresp.last_modified = datetime.datetime.combine(\n    record.updated_at.date(), datetime.time.min\n)","handlingStrategy":"type-guard","validationCode":"import datetime\n\ndef coerce_last_modified(value):\n    if isinstance(value, datetime.date) and not isinstance(value, datetime.datetime):\n        return datetime.datetime.combine(value, datetime.time.min)\n    return value\n\nresp.last_modified = coerce_last_modified(value)","typeGuard":"import datetime\n\ndef is_supported_last_modified(value) -> bool:\n    return value is None or isinstance(value, (int, float, datetime.datetime, str))","tryCatchPattern":"try:\n    resp.last_modified = value\nexcept TypeError:\n    resp.last_modified = str(value)  # or convert to datetime/timestamp","preventionTips":["Use datetime.datetime, not datetime.date, for Last-Modified.","For ORM DateField values, combine with time.min to get a datetime.","Convert pandas.Timestamp via .to_pydatetime() before assigning.","When in doubt, format to an RFC 7231 string and assign the str."],"tags":["aiohttp","web-response","last-modified","datetime","type-error"],"backgroundTag":null,"analyzedSha":"d041d4d0fd48c3f0832084d33be16cf1c4835f85","analyzedAt":"2026-08-11T20:44:15.550Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}