{"id":"bfd0b34620b6245a","repo":"celery/celery","slug":"invalid-expires-value-expires-r-exc","errorCode":null,"errorMessage":"invalid expires value {expires!r}: {exc}","messagePattern":"invalid expires value (.+?): (.+?)","errorType":"exception","errorClass":"InvalidTaskError","httpStatus":null,"severity":"error","filePath":"celery/worker/request.py","lineNumber":151,"sourceCode":"        # timezone means the message is timezone-aware, and the only timezone\n        # supported at this point is UTC.\n        eta = self._request_dict.get('eta')\n        if eta is not None:\n            try:\n                eta = maybe_iso8601(eta)\n            except (AttributeError, ValueError, TypeError) as exc:\n                raise InvalidTaskError(\n                    f'invalid ETA value {eta!r}: {exc}')\n            self._eta = maybe_make_aware(eta, self.tzlocal)\n        else:\n            self._eta = None\n\n        expires = self._request_dict.get('expires')\n        if expires is not None:\n            try:\n                expires = maybe_iso8601(expires)\n            except (AttributeError, ValueError, TypeError) as exc:\n                raise InvalidTaskError(\n                    f'invalid expires value {expires!r}: {exc}')\n            self._expires = maybe_make_aware(expires, self.tzlocal)\n        else:\n            self._expires = None\n\n        delivery_info = message.delivery_info or {}\n        properties = message.properties or {}\n        self._delivery_info = {\n            'exchange': delivery_info.get('exchange'),\n            'routing_key': delivery_info.get('routing_key'),\n            'priority': properties.get('priority'),\n            'redelivered': delivery_info.get('redelivered', False),\n        }\n        self._request_dict.update({\n            'properties': properties,\n            'reply_to': properties.get('reply_to'),\n            'correlation_id': properties.get('correlation_id'),\n            'hostname': self._hostname,","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/celery/celery/blob/571efe81202341310b6257304980ba7898ab0f60/celery/worker/request.py#L133-L169","documentation":"Symmetric to eta: the message's expires field is parsed with maybe_iso8601; on AttributeError/ValueError/TypeError, Request raises InvalidTaskError('invalid expires value {expires!r}: {exc}'). expires may be a datetime or a seconds-int, but the ISO parse path fails on malformed values.","triggerScenarios":"A producer sends a task with apply_async(expires=...) as a malformed ISO string; passing a non-ISO/non-int value that reaches the ISO parser path.","commonSituations":"Confusing expires (relative seconds vs absolute datetime); passing a localized date string; a third-party producer with the wrong format; copying eta-style strings into expires.","solutions":["Pass expires as an int/float number of seconds (relative) or a timezone-aware datetime / ISO-8601 string.","Format datetimes with .isoformat() on the producer side.","Validate the value type before sending and avoid locale-formatted strings."],"exampleFix":"// before\ntask.apply_async(expires='in 5 minutes')  # InvalidTaskError\n\n// after\ntask.apply_async(expires=300)  # 300 seconds\n# or\ntask.apply_async(expires=datetime(2026,8,4,10,15,tzinfo=timezone.utc))","handlingStrategy":"validation","validationCode":"from numbers import Real\nfrom datetime import datetime\n\ndef valid_expires(value):\n    if isinstance(value, Real) and not isinstance(value, bool):\n        return float(value)\n    if isinstance(value, datetime):\n        return value\n    raise ValueError(f'invalid expires value: {value!r}')","typeGuard":"from numbers import Real\nfrom datetime import datetime\n\ndef is_valid_expires(v) -> bool:\n    return (isinstance(v, Real) and not isinstance(v, bool)) or isinstance(v, datetime)","tryCatchPattern":"from celery.exceptions import InvalidTaskError\ntry:\n    task.apply_async(expires=user_expires)\nexcept InvalidTaskError as e:\n    if 'invalid expires' in str(e):\n        # fall back to a numeric seconds value\n        ...\n    else:\n        raise","preventionTips":["Prefer expires as seconds (number) or an aware datetime.","Validate producer-side expires before publishing.","Do not reuse eta-formatted strings for expires."],"tags":["task","expires","message","producer","scheduling"],"analyzedSha":"571efe81202341310b6257304980ba7898ab0f60","analyzedAt":"2026-08-04T20:17:20.567Z","schemaVersion":2}