{"record":{"id":"90d65170293f33b6","repo":"keras-team/keras","slug":"data-not-json-serializable-data","errorCode":null,"errorMessage":"Data not JSON Serializable: {data}","messagePattern":"Data not JSON Serializable: (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"keras/src/legacy/preprocessing/sequence.py","lineNumber":142,"sourceCode":"        targets = np.array([self.targets[row] for row in rows])\n\n        if self.reverse:\n            return samples[:, ::-1, ...], targets\n        return samples, targets\n\n    def get_config(self):\n        \"\"\"Returns the TimeseriesGenerator configuration as Python dictionary.\n\n        Returns:\n            A Python dictionary with the TimeseriesGenerator configuration.\n        \"\"\"\n        data = self.data\n        if type(self.data).__module__ == np.__name__:\n            data = self.data.tolist()\n        try:\n            json_data = json.dumps(data)\n        except TypeError as e:\n            raise TypeError(f\"Data not JSON Serializable: {data}\") from e\n\n        targets = self.targets\n        if type(self.targets).__module__ == np.__name__:\n            targets = self.targets.tolist()\n        try:\n            json_targets = json.dumps(targets)\n        except TypeError as e:\n            raise TypeError(f\"Targets not JSON Serializable: {targets}\") from e\n\n        config = super().get_config()\n        config.update(\n            {\n                \"data\": json_data,\n                \"targets\": json_targets,\n                \"length\": self.length,\n                \"sampling_rate\": self.sampling_rate,\n                \"stride\": self.stride,\n                \"start_index\": self.start_index,","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/legacy/preprocessing/sequence.py#L124-L160","documentation":"TimeseriesGenerator.get_config serializes its data array to JSON for config round-tripping. It converts numpy arrays via tolist(), but any other non-JSON-serializable payload (datetimes, pd.Timestamp, Decimal, custom objects) makes json.dumps raise TypeError, re-raised with this message.","triggerScenarios":"Calling .get_config() (directly or via model-saving utilities that capture configs) on a generator whose data holds datetime objects or an object-dtype numpy array.","commonSituations":"Feeding time-indexed financial/weather data with datetime64 or object-dtype arrays into the legacy generator, then saving the model; migrating old Keras 2.x code forward.","solutions":["Convert datetimes to numeric features before constructing the generator (e.g. epoch seconds via .astype('int64') for datetime64)","Cast object-dtype arrays to float/int yourself","For new code use tf.keras.utils.timeseries_dataset_from_array, which does not embed data in configs"],"exampleFix":"# before\ngen = TimeseriesGenerator(times, values, length=5)  # times: datetime64\n# after\nnums = (times - np.datetime64('1970-01-01')).astype('int64')\ngen = TimeseriesGenerator(nums, values, length=5)","handlingStrategy":"validation","validationCode":"try:\n    json.dumps(np.asarray(data).tolist())\nexcept TypeError:\n    data = np.asarray(data).astype('float64')  # or datetime->int conversion","typeGuard":"def json_safe(a):\n    return all(isinstance(v, (int, float, str, bool, list, dict, type(None)))\n               for v in np.asarray(a).ravel().tolist()[:100])","tryCatchPattern":"try:\n    gen.get_config()\nexcept TypeError as e:\n    if 'not JSON Serializable' not in str(e):\n        raise\n    # convert datetimes to ints and retry","preventionTips":["Convert datetime indices to numeric epoch features at ingestion","Avoid object-dtype arrays for generator data"],"tags":["keras","serialization","json","timeseries"],"backgroundTag":"json-serialization-failed","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}