keras-team/keras · error · ValueError
Cannot adapt layer '{self.name}' after setting a static voca
Error message
Cannot adapt layer '{self.name}' after setting a static vocabulary via `vocabulary` argument or `set_vocabulary()` method. What it means
Keras preprocessing layers that support adapt() cannot be adapted after a static vocabulary has been set. update_state(), which adapt() drives, raises this when _has_input_vocabulary is true, because adapting would silently discard or conflict with the vocabulary you supplied explicitly.
Source
Thrown at keras/src/layers/preprocessing/index_lookup.py:685
or tf.is_tensor(data)
):
progbar = Progbar(target=steps, unit_name="step")
for i, batch in enumerate(data):
if steps is not None and i >= steps:
break
self.update_state(batch)
progbar.update(i + 1)
progbar.update(steps if steps is not None else i + 1, finalize=True)
else:
data = tf_utils.ensure_tensor(data, dtype=self.vocabulary_dtype)
if data.shape.rank == 1:
data = tf.expand_dims(data, -1)
self.update_state(data)
self.finalize_state()
def update_state(self, data):
if self._has_input_vocabulary:
raise ValueError(
f"Cannot adapt layer '{self.name}' after setting a static "
"vocabulary via `vocabulary` argument or "
"`set_vocabulary()` method."
)
data = tf_utils.ensure_tensor(data, dtype=self.vocabulary_dtype)
if data.shape.rank == 0:
data = tf.expand_dims(data, 0)
if data.shape.rank == 1:
# Expand dims on axis 0 for tf-idf. A 1-d tensor
# is a single document.
data = tf.expand_dims(data, 0)
tokens, counts = self._num_tokens(data)
self.token_counts.insert(
tokens, counts + self.token_counts.lookup(tokens)
)
View on GitHub (pinned to 7a34a03db6)
Solutions
- Create a fresh layer without the vocabulary argument and adapt that instead
- Compute the union of old and new vocabulary yourself and call set_vocabulary() with the merged list
- If the layer came from a loaded model, instantiate a new TextVectorization/IndexLookup before adapting
Example fix
// before layer = keras.layers.TextVectorization(vocabulary=vocab) layer.adapt(new_data) // after layer = keras.layers.TextVectorization(max_tokens=...) layer.adapt(new_data)
Defensive patterns
Strategy: validation
Validate before calling
if getattr(layer, '_has_input_vocabulary', False):
cfg = layer.get_config(); cfg.pop('vocabulary', None)
layer = type(layer)(**cfg)
layer.adapt(data) Try / catch
try:
layer.adapt(data)
except ValueError as e:
if 'static vocabulary' in str(e):
cfg = layer.get_config(); cfg.pop('vocabulary', None)
layer = type(layer)(**cfg)
layer.adapt(data)
else:
raise Prevention
- Decide up front: static vocabulary XOR adapt, never both
- Treat vocabularies in loaded models as static
When it happens
Trigger: Creating a layer with a vocabulary argument (e.g. TextVectorization(vocabulary=my_list)) or calling set_vocabulary(), then later calling layer.adapt(data); also re-adapting a layer restored from a saved model that had a vocabulary.
Common situations: Fine-tuning pipelines that load a pretrained vectorizer and try to adapt on new domain data; notebooks that experiment with both static vocab and adapt on the same layer instance.
Related errors
- You need to call `.adapt(dataset)` on the FeatureSpace befor
- Vocabulary file {vocabulary} does not exist.
- Cannot set an empty vocabulary. Received: vocabulary={vocabu
- The passed vocabulary has at least one repeated term. Please
- Found reserved mask token at unexpected location in `vocabul
AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25).
Data as JSON: /api/errors/bf5766834128b53f.
Report an issue: GitHub.