aio-libs/aiohttp · error · ValueError
bad content disposition type
Error message
bad content disposition type {disptype!r} What it means
content_disposition_header raises ValueError when the disposition type (disptype) is empty or contains characters outside the TOKEN set (RFC 2045 token characters). Valid disposition types include 'inline', 'attachment', 'form-data' — they must be non-empty and contain only token characters (no spaces, semicolons, or control chars).
Solutions
- Use a valid disposition type: 'inline', 'attachment', or 'form-data'
- Validate the disposition type against TOKEN characters before calling the function
- Sanitize user-provided disposition types by stripping invalid characters
Example fix
# before
header = content_disposition_header('') # ValueError
# or
header = content_disposition_header('attach;ment') # ValueError
# after
header = content_disposition_header('attachment')
# or validate first
DISPTYPES = {'inline', 'attachment', 'form-data'}
if disptype not in DISPTYPES:
raise ValueError(f'Invalid disposition type: {disptype}') Defensive patterns
Strategy: validation
Validate before calling
import re
TOKEN_RE = re.compile(r"^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$")
def validate_disptype(disptype: str) -> str:
if not disptype or not TOKEN_RE.match(disptype):
raise ValueError(f'Bad disposition type: {disptype!r}')
return disptype Type guard
import re
def is_valid_disposition_type(dt: str) -> bool:
return bool(dt) and bool(re.match(r"^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$", dt)) Try / catch
try:
header = content_disposition_header(disptype)
except ValueError as e:
if 'bad content disposition type' in str(e).lower():
disptype = 'attachment' # safe default
header = content_disposition_header(disptype)
raise Prevention
- Use standard disposition types: inline, attachment, form-data
- Validate user-provided disposition types against RFC token rules
- Never pass empty strings or None as the disposition type
When it happens
Trigger: Calling content_disposition_header('') with an empty string, or passing a disposition type with invalid characters like spaces, semicolons, or non-token separators. Also triggered when set_content_disposition is called on a multipart part with an invalid type.
Common situations: Building Content-Disposition headers dynamically from user input without validation; passing None or empty string as disposition type; typos like 'attach ment' with a space; using a disposition type with special characters.
Related errors
- bad content disposition parameter
- bad content for quoted-string
- Duplicate ' ' header found.
- Invalid HTTP header
- Transfer-Encoding can't be present with Content-Length
AI-assisted analysis of aio-libs/aiohttp@d041d4d0fd (2026-08-11).
Data as JSON: /api/errors/e03301d022a79229.
Report an issue: GitHub.
Appendix: 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 d041d4d0fd)