{"id":"0dd82b81aa5f6944","repo":"pallets/flask","slug":"the-view-function-did-not-return-a-valid-response-0dd82b","errorCode":null,"errorMessage":"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__}.","messagePattern":"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 (.+?)\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/flask/app.py","lineNumber":1344,"sourceCode":"                rv = self.json.response(rv)\n            elif isinstance(rv, BaseResponse) or callable(rv):\n                # evaluate a WSGI callable, or coerce a different response\n                # class to the correct type\n                try:\n                    rv = self.response_class.force_type(\n                        rv,  # type: ignore[arg-type]\n                        request.environ,\n                    )\n                except TypeError as e:\n                    raise TypeError(\n                        f\"{e}\\nThe view function did not return a valid\"\n                        \" response. The return type must be a string,\"\n                        \" dict, list, tuple with headers or status,\"\n                        \" Response instance, or WSGI callable, but it\"\n                        f\" was a {type(rv).__name__}.\"\n                    ).with_traceback(sys.exc_info()[2]) from None\n            else:\n                raise TypeError(\n                    \"The view function did not return a valid\"\n                    \" response. The return type must be a string,\"\n                    \" dict, list, tuple with headers or status,\"\n                    \" Response instance, or WSGI callable, but it was a\"\n                    f\" {type(rv).__name__}.\"\n                )\n\n        rv = t.cast(Response, rv)\n        # prefer the status if it was provided\n        if status is not None:\n            if isinstance(status, (str, bytes, bytearray)):\n                rv.status = status\n            else:\n                rv.status_code = status\n\n        # extend existing headers with provided headers\n        if headers:\n            rv.headers.update(headers)","sourceCodeStart":1326,"sourceCodeEnd":1362,"githubUrl":"https://github.com/pallets/flask/blob/6a2f545bfd8ed31e19066a299296917e034aca58/src/flask/app.py#L1326-L1362","documentation":"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.","triggerScenarios":"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.","commonSituations":"`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.","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."],"exampleFix":"# before\n@app.route(\"/count\")\ndef count():\n    return Item.query.count()  # returns an int\n\n# after\n@app.route(\"/count\")\ndef count():\n    return {\"count\": Item.query.count()}  # dict is JSON-serialized","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"from flask import Response\ndef is_returnable(rv) -> bool:\n    return isinstance(rv, (str, bytes, dict, list, tuple, Response)) or callable(rv)","tryCatchPattern":null,"preventionTips":["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"],"tags":["flask","view-function","serialization","json","return-value"],"analyzedSha":"6a2f545bfd8ed31e19066a299296917e034aca58","analyzedAt":"2026-07-31T19:13:49.921Z","schemaVersion":2}