pallets/flask · error · TypeError
The view function did not return a valid response. The…
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 when a view returns a value that matches none of the accepted types (str, bytes, bytearray, dict, list, iterator, BaseResponse, callable). This is the catch-all TypeError for an unhandleable return value.
Solutions
- Wrap the value in jsonify(...) for dict/list-like data, or str(...) for primitives.
- For a status-only response, return a tuple: ('', 204).
- Register a custom response class or FORCED response type if a domain object must be returned.
Example fix
// before
@app.route('/count')
def count():
return 42 # raises
// after
@app.route('/count')
def count():
return jsonify({'count': 42}) Defensive patterns
Strategy: validation
Validate before calling
from collections.abc import Iterator
ACCEPTED = (str, bytes, bytearray, dict, list, Iterator)
def is_acceptable_return(rv) -> bool:
return isinstance(rv, ACCEPTED) or callable(rv) Type guard
def is_acceptable_return(rv) -> bool:
return isinstance(rv, (str, bytes, bytearray, dict, list)) or callable(rv) Try / catch
try:
return rv
except TypeError as e:
if 'return type' in str(e):
return jsonify({'error': 'serialization failed'}), 500
raise Prevention
- Wrap primitives with jsonify()/str() before returning.
- Return Response objects for non-trivial types.
- Register a custom JSON encoder/response class for domain objects.
When it happens
Trigger: A view returns an int, float, bool, None-already-handled, custom object, tuple-of-wrong-shape-already-unpacked object, etc. Example: return 42.
Common situations: Returning a bare integer status code expecting it to set status; returning a model/dataclass object that isn't serializable; returning True/False from a check.
Related errors
- \nThe view function did not return a valid response. The…
- The view function did not return a valid response tuple…
- The view function for
- Allowed methods must be a list of strings, for example…
- is an instance, not a class. Handlers can only be…
AI-assisted analysis of pallets/flask@3596b1ab61 (2026-08-11).
Data as JSON: /api/errors/0dd82b81aa5f6944.
Report an issue: GitHub.
Appendix: source
Thrown at src/flask/app.py:1347
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 3596b1ab61)