{"record":{"id":"ad023036bdb2e2d7","repo":"keras-team/keras","slug":"you-need-to-call-adapt-dataset-on-the-features","errorCode":null,"errorMessage":"You need to call `.adapt(dataset)` on the FeatureSpace before you can start using it.","messagePattern":"You need to call `\\.adapt\\(dataset\\)` on the FeatureSpace before you can start using it\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"keras/src/layers/preprocessing/feature_space.py","lineNumber":741,"sourceCode":"                        f\"has not been encoded (it has dtype {dtype}). \"\n                        \"Consider using `output_mode='dict'`.\"\n                    )\n                features_to_concat.append(feature)\n            else:\n                output_dict[name] = feature\n\n        if self.output_mode == \"concat\":\n            self.concat = TFDConcat(axis=-1)\n            return self.concat(features_to_concat)\n        else:\n            return output_dict\n\n    def _check_if_adapted(self):\n        if not self._is_adapted:\n            if not self._list_adaptable_preprocessors():\n                self._is_adapted = True\n            else:\n                raise ValueError(\n                    \"You need to call `.adapt(dataset)` on the FeatureSpace \"\n                    \"before you can start using it.\"\n                )\n\n    def _check_if_built(self):\n        if not self._sublayers_built:\n            self._check_if_adapted()\n            # Finishes building\n            self.get_encoded_features()\n            self._sublayers_built = True\n\n    def _convert_input(self, x):\n        if not isinstance(x, (tf.Tensor, tf.SparseTensor, tf.RaggedTensor)):\n            if not isinstance(x, (list, tuple, int, float)):\n                x = backend.convert_to_numpy(x)\n            x = tf.convert_to_tensor(x)\n        return x\n","sourceCodeStart":723,"sourceCodeEnd":759,"githubUrl":"https://github.com/keras-team/keras/blob/7a34a03db60bf60042242d6a556fc3be119046a5/keras/src/layers/preprocessing/feature_space.py#L723-L759","documentation":"FeatureSpace must be adapted to data before use whenever it contains adaptable preprocessors (lookup/vocabulary layers). adapt() computes vocabularies; without it the layer cannot translate raw values to indices and refuses to run.","triggerScenarios":"Calling fs.get_encoded_features(), fs(data), or _check_if_built paths before any fs.adapt(dataset) call, while the feature specs include vocabulary/hash-based preprocessors.","commonSituations":"Building a model that calls FeatureSpace before adapt(); loading a FeatureSpace config without its adapted state; skipping adapt because the data 'already looks fine'.","solutions":["Call fs.adapt(dataset) on your raw (unencoded) training data before get_encoded_features()/__call__","If there are truly no adaptable features, ensure none of the feature specs create lookup layers","Re-adapt after changing feature specs"],"exampleFix":"// before\nfs = FeatureSpace(features)\ninputs = fs.get_encoded_features()  # ValueError\n// after\nfs = FeatureSpace(features)\nfs.adapt(train_ds)\ninputs = fs.get_encoded_features()","handlingStrategy":"validation","validationCode":"if fs._list_adaptable_preprocessors() and not fs._is_adapted:\n    fs.adapt(raw_train_data)  # adapt before use","typeGuard":"def is_adapted(fs):\n    return fs._is_adapted or not fs._list_adaptable_preprocessors()","tryCatchPattern":"catch ValueError around model/FeatureSpace usage and call fs.adapt(unlabeled_data) before retrying","preventionTips":["Always call fs.adapt(train_ds) once after construction, before training or inference","Save/load via fs.save()/FeatureSpace.load to preserve adapted state across restarts"],"tags":["keras","feature-space","adapt","state"],"backgroundTag":"missing-required-initialization","analyzedSha":"7a34a03db60bf60042242d6a556fc3be119046a5","analyzedAt":"2026-08-25T21:25:25.994Z","schemaVersion":2},"datasetVersion":"2026-08-26T02:17:13.382Z"}