pallets/flask · warning · DebugFilesKeyError

You tried to access the file

Error message

You tried to access the file {key!r} in the request.files dictionary but it does not exist. The mimetype for the request is {request.mimetype!r} instead of 'multipart/form-data' which means that no file contents were transmitted. To fix this error you should provide enctype="multipart/form-data" in your form.

What it means

attach_enctype_error_multidict (debug mode only) patches request.files.__getitem__ to raise DebugFilesKeyError when a missing file key IS present in request.form. This means the field name was submitted as a form value, not as a file upload—almost always because the HTML form lacks enctype="multipart/form-data", so the browser sent the field as text and request.mimetype is not multipart/form-data.

Solutions

  1. Add enctype="multipart/form-data" to the <form> element: <form method="post" enctype="multipart/form-data">.
  2. If uploading via fetch/axios, send a FormData object so the browser sets the correct multipart Content-Type (do not set Content-Type manually).
  3. Use request.files.get('upload') with a None check, and validate request.mimetype == 'multipart/form-data' for a clearer non-debug error.

Example fix

<!-- before -->
<form method="post">
  <input type="file" name="upload">
</form>

<!-- after -->
<form method="post" enctype="multipart/form-data">
  <input type="file" name="upload">
</form>
Defensive patterns

Strategy: validation

Validate before calling

def is_multipart_upload(request) -> bool:
    return request.mimetype == 'multipart/form-data'

# in the view before accessing files
if not is_multipart_upload(request):
    return 'Form must use enctype=multipart/form-data', 400

Type guard

def is_multipart(request) -> bool:
    return request.mimetype == 'multipart/form-data'

Try / catch

from flask import request
try:
    f = request.files['upload']
except KeyError:
    if request.mimetype != 'multipart/form-data':
        return 'Missing enctype=multipart/form-data', 400
    raise

Prevention

When it happens

Trigger: In debug mode, a view does request.files['upload'] but the form tag has no enctype attribute (defaults to application/x-www-form-urlencoded). The key exists in request.form (the filename string) but not in request.files, triggering the patched KeyError with the descriptive mimetype message. Only attaches when app.debug is True.

Common situations: File upload form missing enctype. Switching a form to handle uploads but forgetting the enctype attribute. AJAX upload sending the wrong Content-Type header. Using a FormData object incorrectly client-side.

Related errors


AI-assisted analysis of pallets/flask@3596b1ab61 (2026-08-11). Data as JSON: /api/errors/b432baa05520c09e. Report an issue: GitHub.

Appendix: source

Thrown at src/flask/debughelpers.py:98

def attach_enctype_error_multidict(request: Request) -> None:
    """Patch ``request.files.__getitem__`` to raise a descriptive error
    about ``enctype=multipart/form-data``.

    :param request: The request to patch.
    :meta private:
    """
    oldcls = request.files.__class__

    class newcls(oldcls):  # type: ignore[valid-type, misc]
        def __getitem__(self, key: str) -> t.Any:
            try:
                return super().__getitem__(key)
            except KeyError as e:
                if key not in request.form:
                    raise

                raise DebugFilesKeyError(request, key).with_traceback(
                    e.__traceback__
                ) from None

    newcls.__name__ = oldcls.__name__
    newcls.__module__ = oldcls.__module__
    request.files.__class__ = newcls


def _dump_loader_info(loader: BaseLoader) -> t.Iterator[str]:
    yield f"class: {type(loader).__module__}.{type(loader).__name__}"
    for key, value in sorted(loader.__dict__.items()):
        if key.startswith("_"):
            continue
        if isinstance(value, (tuple, list)):
            if not all(isinstance(x, str) for x in value):
                continue
            yield f"{key}:"
            for item in value:

View on GitHub (pinned to 3596b1ab61)