{"id":"d69686dda339bade","repo":"pallets/flask","slug":"object-of-type-type-o-name-is-not-json-seri","errorCode":null,"errorMessage":"Object of type {type(o).__name__} is not JSON serializable","messagePattern":"Object of type (.+?) is not JSON serializable","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/flask/json/provider.py","lineNumber":121,"sourceCode":"        \"\"\"\n        obj = self._prepare_response_obj(args, kwargs)\n        return self._app.response_class(self.dumps(obj), mimetype=\"application/json\")\n\n\ndef _default(o: t.Any) -> t.Any:\n    if isinstance(o, date):\n        return http_date(o)\n\n    if isinstance(o, (decimal.Decimal, uuid.UUID)):\n        return str(o)\n\n    if dataclasses and dataclasses.is_dataclass(o):\n        return dataclasses.asdict(o)  # type: ignore[arg-type]\n\n    if hasattr(o, \"__html__\"):\n        return str(o.__html__())\n\n    raise TypeError(f\"Object of type {type(o).__name__} is not JSON serializable\")\n\n\nclass DefaultJSONProvider(JSONProvider):\n    \"\"\"Provide JSON operations using Python's built-in :mod:`json`\n    library. Serializes the following additional data types:\n\n    -   :class:`datetime.datetime` and :class:`datetime.date` are\n        serialized to :rfc:`822` strings. This is the same as the HTTP\n        date format.\n    -   :class:`uuid.UUID` is serialized to a string.\n    -   :class:`dataclasses.dataclass` is passed to\n        :func:`dataclasses.asdict`.\n    -   :class:`~markupsafe.Markup` (or any object with a ``__html__``\n        method) will call the ``__html__`` method to get a string.\n    \"\"\"\n\n    default: t.Callable[[t.Any], t.Any] = staticmethod(_default)\n    \"\"\"Apply this function to any object that :meth:`json.dumps` does","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/pallets/flask/blob/6a2f545bfd8ed31e19066a299296917e034aca58/src/flask/json/provider.py#L103-L139","documentation":"Raised by Flask's DefaultJSONProvider fallback serializer (`_default` in src/flask/json/provider.py) when an object reaches the end of its type-conversion chain. Flask extends stdlib json with support for date/datetime (RFC 822 strings), Decimal, UUID, dataclasses, and objects with `__html__` (Markup); anything else raises this TypeError because Python's `json.dumps` has no representation for it.","triggerScenarios":"Calling `jsonify(obj)`, `flask.json.dumps(obj)`, or returning a dict/list from a view that contains an unsupported type — e.g. a set, bytes, a generator, a SQLAlchemy model instance, a numpy int64/float32/ndarray, a custom class, or a Decimal-wrapping proxy that isn't one of the handled types.","commonSituations":"Returning SQLAlchemy ORM objects or query results directly from a route; passing numpy/pandas values from data-science code into jsonify; serializing sets built for dedup; returning bytes from crypto/file APIs; after upgrading to Flask 2.2+ where the custom-JSONEncoder pattern (`app.json_encoder`) was deprecated in favor of providers, breaking old custom encoders.","solutions":["Convert the offending object to a JSON-native type before jsonify: `list(my_set)`, `my_bytes.decode()`, `int(np_value)`, or a dict via a `to_dict()` method / marshmallow / pydantic `.model_dump()`.","Subclass DefaultJSONProvider, override `default()` to handle your types, and set `app.json = MyProvider(app)` (Flask 2.2+).","For dataclass-like models, define the model as a `@dataclass` or give it a `__html__`-free `to_dict()` and serialize that.","On Flask <2.2, set `app.json_encoder` to a custom `json.JSONEncoder` subclass instead."],"exampleFix":"# before\nreturn jsonify({\"ids\": {1, 2, 3}})  # TypeError: Object of type set is not JSON serializable\n\n# after\nreturn jsonify({\"ids\": sorted({1, 2, 3})})\n\n# or globally (Flask 2.2+):\nclass MyJSONProvider(DefaultJSONProvider):\n    @staticmethod\n    def default(o):\n        if isinstance(o, set):\n            return list(o)\n        return DefaultJSONProvider.default(o)\napp.json = MyJSONProvider(app)","handlingStrategy":"validation","validationCode":"import json\ndef is_json_safe(obj):\n    try:\n        json.dumps(obj, default=str)  # probe\n        return True\n    except TypeError:\n        return False\n# Better: convert before passing to jsonify\nfrom dataclasses import asdict, is_dataclass\npayload = asdict(obj) if is_dataclass(obj) else obj","typeGuard":"def is_serializable(o):\n    return isinstance(o, (dict, list, tuple, str, int, float, bool, type(None)))","tryCatchPattern":"try:\n    return jsonify(data)\nexcept TypeError:\n    app.logger.exception('non-serializable payload')\n    return jsonify({'error': 'internal serialization error'}), 500","preventionTips":["Convert ORM models, datetimes, Decimals, and dataclasses to plain dicts/strings before calling jsonify()","Register a custom JSONProvider (subclass DefaultJSONProvider and override default()) for domain types used app-wide","Return only primitives, dicts, and lists from view functions","Add a serialization layer (marshmallow/pydantic) so views never pass raw objects to jsonify"],"tags":["flask","json","serialization","python"],"analyzedSha":"6a2f545bfd8ed31e19066a299296917e034aca58","analyzedAt":"2026-07-31T19:13:49.921Z","schemaVersion":2}