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

  1. Create a fresh layer without the vocabulary argument and adapt that instead
  2. Compute the union of old and new vocabulary yourself and call set_vocabulary() with the merged list
  3. 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

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


AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25). Data as JSON: /api/errors/bf5766834128b53f. Report an issue: GitHub.