keras-team/keras · error · ValueError

`num_oov_indices` must be greater than or equal to 0. Receiv

Error message

`num_oov_indices` must be greater than or equal to 0. Received: num_oov_indices={num_oov_indices}

What it means

Keras IndexLookup reserves `num_oov_indices` buckets at the front of its index space for out-of-vocabulary tokens. The constructor validates this count is >= 0; a negative value cannot allocate buckets and fails fast at layer creation.

Source

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

        salt=None,
        **kwargs,
    ):
        # If max_tokens is set, the value must be greater than 1 - otherwise we
        # are creating a 0-element vocab, which doesn't make sense.
        if max_tokens is not None and max_tokens <= 1:
            raise ValueError(
                "If set, `max_tokens` must be greater than 1. "
                f"Received: max_tokens={max_tokens}"
            )

        if pad_to_max_tokens and max_tokens is None:
            raise ValueError(
                "If pad_to_max_tokens is True, must set `max_tokens`. "
                f"Received: max_tokens={max_tokens}"
            )

        if num_oov_indices < 0:
            raise ValueError(
                "`num_oov_indices` must be greater than or equal to 0. "
                f"Received: num_oov_indices={num_oov_indices}"
            )

        argument_validation.validate_string_arg(
            oov_method,
            allowable_strings=("floormod", "farmhash"),
            caller_name=self.__class__.__name__,
            arg_name="oov_method",
        )

        if salt is not None:
            if (
                tf.as_dtype(vocabulary_dtype).is_integer
                and oov_method != "farmhash"
            ):
                raise ValueError(
                    "`salt` can only be used when `oov_method='farmhash'`. "

View on GitHub (pinned to 7a34a03db6)

Solutions

  1. Pass an explicit non-negative integer: 0 disables OOV buckets, 1 is the typical default.
  2. If the value is computed, clamp or assert it before constructing the layer: `assert num_oov_indices >= 0`.
  3. Remember `max_tokens` must cover OOV buckets plus mask token when `pad_to_max_tokens=True`.

Example fix

# before
layer = IndexLookup(max_tokens=20000, num_oov_indices=n_buckets - extra)

# after
n_buckets = max(0, n_buckets - extra)
layer = IndexLookup(max_tokens=20000, num_oov_indices=n_buckets)
Defensive patterns

Strategy: validation

Validate before calling

if not isinstance(num_oov_indices, int) or num_oov_indices < 0:
    raise ValueError('num_oov_indices must be a non-negative int')
layer = IndexLookup(num_oov_indices=num_oov_indices)

Type guard

def valid_num_oov(n) -> bool:
    return isinstance(n, int) and not isinstance(n, bool) and n >= 0

Try / catch

try:
    layer = IndexLookup(num_oov_indices=n)
except ValueError:
    n = max(0, n)
    layer = IndexLookup(num_oov_indices=n)

Prevention

When it happens

Trigger: Calling `IndexLookup(max_tokens=..., num_oov_indices=-1)`, or computing the value dynamically (e.g. `num_oov_indices=max_tokens - expected_vocab_size`) so it goes negative before the constructor validates it.

Common situations: Scripts that derive OOV bucket counts from dataset statistics, refactored StringLookup configs, or copy-pasted parameter sets where the variable holds a negative sentinel.

Related errors


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