psf/requests · error · TypeError
max-age: {morsel['max-age']} must be integer
Error message
max-age: {morsel['max-age']} must be integer What it means
A TypeError raised by requests.cookies.morsel_to_cookie() in src/requests/cookies.py when converting a http.cookies.Morsel into a cookiejar Cookie. The Max-Age attribute must be convertible with int() so it can be added to time.time() to compute an absolute expiry; a non-integer value raises ValueError internally, which is re-raised as this TypeError.
Source
Thrown at src/requests/cookies.py:539
result.update(kwargs)
result["port_specified"] = bool(result["port"])
result["domain_specified"] = bool(result["domain"])
result["domain_initial_dot"] = result["domain"].startswith(".")
result["path_specified"] = bool(result["path"])
return cookielib.Cookie(**result)
def morsel_to_cookie(morsel: Morsel[Any]) -> Cookie:
"""Convert a Morsel object into a Cookie containing the one k/v pair."""
expires: int | None = None
if morsel["max-age"]:
try:
expires = int(time.time() + int(morsel["max-age"]))
except ValueError:
raise TypeError(f"max-age: {morsel['max-age']} must be integer")
elif morsel["expires"]:
time_template = "%a, %d-%b-%Y %H:%M:%S GMT"
expires = calendar.timegm(time.strptime(morsel["expires"], time_template))
return create_cookie(
comment=morsel["comment"],
comment_url=bool(morsel["comment"]),
discard=False,
domain=morsel["domain"],
expires=expires,
name=morsel.key,
path=morsel["path"],
port=None,
rest={"HttpOnly": morsel["httponly"]},
rfc2109=False,
secure=bool(morsel["secure"]),
value=morsel.value,
version=morsel["version"] or 0,
)View on GitHub ↗ (pinned to 414f0513c3)
Solutions
- Sanitize the Morsel before conversion: coerce morsel['max-age'] = str(int(float(raw))) or delete the attribute and rely on 'expires'.
- Fix the producing side (server/framework) to emit an integer Max-Age per RFC 6265.
- If the max-age is meaningless, remove it and set morsel['expires'] to an RFC 1123 date string instead.
Example fix
# before morsel['max-age'] = '3600.5' cookie = morsel_to_cookie(morsel) # TypeError # after morsel['max-age'] = str(int(float(morsel['max-age']))) cookie = morsel_to_cookie(morsel)
Defensive patterns
Strategy: validation
Validate before calling
morsel = cookie_obj # http.cookies.Morsel
if morsel['max-age']:
try:
int(morsel['max-age'])
except ValueError:
morsel['max-age'] = '' # strip malformed max-age before conversion Type guard
def has_valid_max_age(morsel):
ma = morsel.get('max-age', '')
if not ma:
return True
try:
int(ma)
return True
except (TypeError, ValueError):
return False Try / catch
try:
cookie = requests.cookies.morsel_to_cookie(morsel)
except TypeError:
morsel['max-age'] = ''
cookie = requests.cookies.morsel_to_cookie(morsel) Prevention
- Validate max-age is an integer string before calling morsel_to_cookie() on Morsels built from untrusted Set-Cookie data
- When constructing Morsels yourself, set max-age with str(int(seconds)), never floats like '3600.0'
- Sanitize or drop malformed max-age from third-party servers rather than letting a TypeError abort processing
When it happens
Trigger: Calling morsel_to_cookie() (directly, or via requests.utils.add_dict_to_cookiejar/cookiejar_from_dict paths that accept Morsels) on a Morsel whose 'max-age' is set to a non-integer string — e.g. morsel['max-age'] = '3600.5', 'session', or an empty-but-truthy garbage value produced by a noncompliant server or hand-built SimpleCookie.
Common situations: Parsing Set-Cookie headers from noncompliant servers that emit fractional or textual Max-Age values; test fixtures constructing Morsels by hand; frameworks that stuff float seconds into max-age.
Related errors
- create_cookie() got unexpected keyword arguments: {list(bada
- Cookie headers should be added with add_unredirected_header(
- name={name!r}, domain={domain!r}, path={path!r}
- There are multiple cookies with name, {name!r}
- You can only merge into CookieJar
AI-assisted analysis of psf/requests@414f0513c3 (2026-07-31).
Data as JSON: /data/errors/730b2a9f5360bdc4.json.
Report an issue: GitHub ↗.