pallets/flask · error · TypeError
The view function did not return a valid response. The retur
Error message
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:1344) when the view's return value matches none of the supported types: it is not a str/bytes/bytearray/iterator (body), not a dict or list (JSON), not a Response/BaseResponse, and not callable. Flask cannot serialize arbitrary Python objects into an HTTP response, so it rejects the value and names the offending type.
Source
Thrown at src/flask/app.py:1344
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:
if isinstance(status, (str, bytes, bytearray)):
rv.status = status
else:
rv.status_code = status
# extend existing headers with provided headers
if headers:
rv.headers.update(headers)View on GitHub ↗ (pinned to 6a2f545bfd)
Solutions
- Convert the value to a supported type: wrap objects in `jsonify(...)` or return a dict/list built from the object (e.g. `return model.to_dict()`).
- For a bare status code, return a tuple with an empty body: `return '', 204` — or use `abort(404)` for error statuses.
- Serialize non-JSON-native types (Decimal, datetime, sets) to str/list/dict before returning, or register a custom JSON provider.
- Return `str(value)` for simple scalar responses.
Example fix
# before
@app.route("/count")
def count():
return Item.query.count() # returns an int
# after
@app.route("/count")
def count():
return {"count": Item.query.count()} # dict is JSON-serialized 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) Prevention
- Same contract as [18] for the body element inside a returned tuple: string, dict, list, Response, or WSGI callable
- Convert numbers and custom objects explicitly: `str(count)` or `jsonify(payload)`
- Type-annotate views with ResponseReturnValue and enforce with mypy in CI
When it happens
Trigger: Returning an int (`return 204`), bool, float, set, ORM model instance, dataclass, numpy array, or any custom object from a view. The message's `{type(rv).__name__}` tells you exactly which type was returned. Also fires for the body element of a (body, status) tuple when the body is an unsupported type.
Common situations: `return 200` or `return 404` intending a bare status code (a body is required — use `('', 404)` or `abort(404)`); returning SQLAlchemy model objects or query results expecting automatic JSON; returning a `set` (not JSON-serializable-typed here, unlike dict/list); returning a Decimal/datetime directly; forgetting `jsonify` for objects that aren't plain dicts/lists.
Related errors
- The view function did not return a valid response tuple. The
- The view function for {request.endpoint!r} did not return a
- {e} The view function did not return a valid response. The r
- Object of type {type(o).__name__} is not JSON serializable
- Tag '{key}' is already registered.
AI-assisted analysis of pallets/flask@6a2f545bfd (2026-07-31).
Data as JSON: /data/errors/0dd82b81aa5f6944.json.
Report an issue: GitHub ↗.