aio-libs/aiohttp · error · ValueError
bad content disposition type {disptype!r}
Error message
bad content disposition type {disptype!r} What it means
Raised by content_disposition_header when disptype is empty or contains characters outside the HTTP TOKEN set (must be a subset of TOKEN: printable ASCII minus separators/controls). The disposition type (inline/attachment/form-data) must be a valid RFC 9110 token.
Source
Thrown at aiohttp/helpers.py:440
"""Sets ``Content-Disposition`` header for MIME.
This is the MIME payload Content-Disposition header from RFC 2183
and RFC 7579 section 4.2, not the HTTP Content-Disposition from
RFC 6266.
disptype is a disposition type: inline, attachment, form-data.
Should be valid extension token (see RFC 2183)
quote_fields performs value quoting to 7-bit MIME headers
according to RFC 7578. Set to quote_fields to False if recipient
can take 8-bit file names and field values.
_charset specifies the charset to use when quote_fields is True.
params is a dict with disposition params.
"""
if not disptype or not (TOKEN > set(disptype)):
raise ValueError(f"bad content disposition type {disptype!r}")
value = disptype
if params:
lparams = []
for key, val in params.items():
if not key or not (TOKEN > set(key)):
raise ValueError(f"bad content disposition parameter {key!r}={val!r}")
if quote_fields:
if key.lower() == "filename":
qval = quote(val, "", encoding=_charset)
lparams.append((key, '"%s"' % qval))
else:
try:
qval = quoted_string(val)
except ValueError:
qval = "".join(
(_charset, "''", quote(val, "", encoding=_charset))
)View on GitHub (pinned to c0ef574e29)
Solutions
- Pass a bare token like 'attachment', 'inline', or 'form-data'.
- Validate disptype against TOKEN before calling.
- Put parameters in the params dict, not appended to disptype.
Example fix
// before
content_disposition_header('attachment; name="x"')
// after
content_disposition_header('attachment', params={'name': 'x'}) Defensive patterns
Strategy: validation
Validate before calling
import re
TOKEN = re.compile(r"^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$")
def safe_disptype(t):
if not TOKEN.fullmatch(t):
raise ValueError(f'bad disptype {t!r}')
return t Type guard
def is_valid_disptype(t) -> bool:
import re
TOKEN = set("!#$%&'*+-.^_`|~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
return bool(t) and TOKEN > set(t) Prevention
- Use canonical tokens: inline, attachment, form-data.
- Keep parameters in the params dict, not in disptype.
- Validate disptype against TOKEN before constructing the header.
When it happens
Trigger: content_disposition_header('') or content_disposition_header('attach ment') (space), content_disposition_header('attach"ment') (quote), or a disposition type with '/' .
Common situations: Building Content-Disposition from unvalidated user input; templating disptype with whitespace; passing a MIME-style 'attachment; x' blob as the disptype.
Related errors
- bad content disposition parameter {key!r}={val!r}
- bad content for quoted-string {content!r}
- Invalid Content-Length header: {content_length_hdr!r}
- Value {value!r} is not a valid etag. Maybe it contains '"'?
- Missing 'Host' header in request.
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/e03301d022a79229.json.
Report an issue: GitHub.