keras-team/keras · error · RuntimeError

When using `output_mode={self.output_mode}` and `pad_to_max_

Error message

When using `output_mode={self.output_mode}` and `pad_to_max_tokens=False`, you must set the layer's vocabulary before calling it. Either pass a `vocabulary` argument to the layer, or call `adapt` with some sample data.

What it means

For output modes other than 'int' (e.g. 'count', 'tf_idf', multi-hot) with pad_to_max_tokens=False, the layer must know the vocabulary size at call time to size the output vector. _ensure_known_vocab_size() raises when _frozen_vocab_size is None, i.e. the layer was never given a vocabulary and never adapted.

Source

Thrown at keras/src/layers/preprocessing/index_lookup.py:1033

            return tf.sparse.expand_dims(inputs, axis)
        else:
            return tf.expand_dims(inputs, axis)

    def _oov_start_index(self):
        return (
            1
            if self.mask_token is not None and self.output_mode == "int"
            else 0
        )

    def _token_start_index(self):
        return self._oov_start_index() + self.num_oov_indices

    def _ensure_known_vocab_size(self):
        if self.output_mode == "int" or self.pad_to_max_tokens:
            return
        if self._frozen_vocab_size is None:
            raise RuntimeError(
                f"When using `output_mode={self.output_mode}` "
                "and `pad_to_max_tokens=False`, "
                "you must set the layer's vocabulary before calling it. Either "
                "pass a `vocabulary` argument to the layer, or call `adapt` "
                "with some sample data."
            )

    def _ensure_vocab_size_unchanged(self):
        if self.output_mode == "int" or self.pad_to_max_tokens:
            return

        with tf.init_scope():
            new_vocab_size = self.vocabulary_size()

        if (
            self._frozen_vocab_size is not None
            and new_vocab_size != self._frozen_vocab_size
        ):

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Call layer.adapt(sample_data) before using the layer
  2. Pass a vocabulary at construction: TextVectorization(vocabulary=...)
  3. Set pad_to_max_tokens=True with max_tokens so the output width is fixed without a vocabulary

Example fix

// before
layer = TextVectorization(output_mode='multi_hot')
model(layer(inputs))
// after
layer = TextVectorization(output_mode='multi_hot')
layer.adapt(train_texts)
model(layer(inputs))
Defensive patterns

Strategy: validation

Validate before calling

if layer.output_mode != 'int' and not layer.pad_to_max_tokens:
    assert layer.vocabulary_size() > 0, 'adapt or set vocabulary first'

Prevention

When it happens

Trigger: Creating IndexLookup/TextVectorization(output_mode='multi_hot'|'count'|'tf_idf', pad_to_max_tokens=False) with no vocabulary argument and calling it before adapt(); building a model with such a layer and calling model.predict without prior vocabulary setup.

Common situations: Prototyping multi-hot encoders in a functional model without adapt; assuming the layer infers vocab size from the first batch like 'int' mode does.

Related errors


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