pallets/flask · error · TypeError
{e} The view function did not return a valid response. The r
Error message
{e}
The view function did not return a valid response. The return type must be a string, dict, list, tuple with headers or status, Response instance, or WSGI callable, but it was a {type(rv).__name__}. What it means
Raised in `Flask.make_response()` (src/flask/app.py:1336) when the return value looked like a Response instance (another framework's `BaseResponse` subclass) or a callable/WSGI app, but `response_class.force_type()` failed to coerce it, raising a TypeError. Flask re-raises with the original coercion error (`{e}`) prepended plus the list of valid return types, because a callable that isn't actually a valid WSGI application cannot be turned into a Flask Response.
Source
Thrown at src/flask/app.py:1336
# special logic
rv = self.response_class(
rv, # pyright: ignore
status=status,
headers=headers, # type: ignore[arg-type]
)
status = headers = None
elif isinstance(rv, (dict, list)):
rv = self.json.response(rv)
elif isinstance(rv, BaseResponse) or callable(rv):
# evaluate a WSGI callable, or coerce a different response
# class to the correct type
try:
rv = self.response_class.force_type(
rv, # type: ignore[arg-type]
request.environ,
)
except TypeError as e:
raise TypeError(
f"{e}\nThe view function did not return a valid"
" response. The return type must be a string,"
" dict, list, tuple with headers or status,"
" Response instance, or WSGI callable, but it"
f" was a {type(rv).__name__}."
).with_traceback(sys.exc_info()[2]) from None
else:
raise TypeError(
"The view function did not return a valid"
" response. The return type must be a string,"
" dict, list, tuple with headers or status,"
" Response instance, or WSGI callable, but it was a"
f" {type(rv).__name__}."
)
rv = t.cast(Response, rv)
# prefer the status if it was provided
if status is not None:View on GitHub ↗ (pinned to 6a2f545bfd)
Solutions
- Read the first line of the message (the original coercion error) — it identifies why werkzeug's force_type failed.
- If you meant to call a function, add the parentheses: `return build_response()` not `return build_response`.
- Convert the object explicitly before returning: `return make_response(str(obj))`, `return jsonify(obj_dict)`, or construct a `flask.Response` yourself.
- Only return a raw callable if it is a genuine WSGI application accepting `(environ, start_response)`.
Example fix
# before
def build_report():
return render_template("report.html")
@app.route("/report")
def report():
return build_report # returned the function object
# after
@app.route("/report")
def report():
return build_report() Defensive patterns
Strategy: type-guard
Type guard
from flask import Response
def is_returnable(rv) -> bool:
return isinstance(rv, (str, bytes, dict, list, tuple, Response)) or callable(rv) Try / catch
try:
resp = app.make_response(rv)
except TypeError:
# rv was an unsupported type (e.g. int, ORM model, generator object)
raise Prevention
- Serialize objects before returning: use `jsonify(obj)` or `dict`/`list` for JSON, never raw ORM models or ints
- Annotate views with `-> flask.typing.ResponseReturnValue` and run mypy
- Watch for returning a function instead of calling it (missing parentheses)
When it happens
Trigger: Returning a callable that doesn't implement the WSGI signature `(environ, start_response)` — e.g. a function, lambda, class, or partially-applied object returned by mistake; returning a foreign response object whose iteration/coercion fails inside `werkzeug.Response.force_type`.
Common situations: Returning a function reference instead of calling it (`return my_handler` instead of `return my_handler()`); returning a class like `return MyModel`; returning an ORM object or generator-producing callable; mixing response objects from an incompatible library version where force_type's coercion breaks.
Related errors
- The view function did not return a valid response tuple. The
- The view function for {request.endpoint!r} did not return a
- The view function did not return a valid response. The retur
- Working outside of application context. Attempted to use fu
- Working outside of request context. Attempted to use functi
AI-assisted analysis of pallets/flask@6a2f545bfd (2026-07-31).
Data as JSON: /data/errors/d469f840bcac36bf.json.
Report an issue: GitHub ↗.