keras-team/keras · error · ValueError
Found reserved OOV token at unexpected location in `vocabula
Error message
Found reserved OOV token at unexpected location in `vocabulary`. Note that passed `vocabulary` does not need to include the OOV and mask tokens. Either remove all mask and OOV tokens, or include them only at the start of the vocabulary in precisely this order: {special_tokens}. Received: oov_token={self.oov_token} at vocabulary index {oov_index} What it means
The OOV-token counterpart of the mask-token check, applied on inverted (index-to-token) layers: if the oov_token appears in the passed vocabulary outside its reserved head slot, the reverse mapping would be ambiguous.
Source
Thrown at keras/src/layers/preprocessing/index_lookup.py:538
mask_index = np.argwhere(vocabulary == self.mask_token)[-1]
raise ValueError(
"Found reserved mask token at unexpected location in "
"`vocabulary`. Note that passed `vocabulary` does not need to "
"include the OOV and mask tokens. Either remove all mask and "
"OOV tokens, or include them only at the start of the "
f"vocabulary in precisely this order: {special_tokens}. "
f"Received: mask_token={self.mask_token} at "
f"vocabulary index {mask_index}"
)
# Only error out for oov_token when invert=True. When invert=False,
# oov_token is unused during lookup.
if (
self.oov_token is not None
and self.invert
and self.oov_token in tokens
):
oov_index = np.argwhere(vocabulary == self.oov_token)[-1]
raise ValueError(
"Found reserved OOV token at unexpected location in "
"`vocabulary`. Note that passed `vocabulary` does not need to "
"include the OOV and mask tokens. Either remove all mask and "
"OOV tokens, or include them only at the start of the "
f"vocabulary in precisely this order: {special_tokens}. "
f"Received: oov_token={self.oov_token} at "
f"vocabulary index {oov_index}"
)
new_vocab_size = token_start + len(tokens)
if self.max_tokens is not None and (new_vocab_size > self.max_tokens):
raise ValueError(
"Attempted to set a vocabulary larger than the maximum vocab "
f"size. Received vocabulary size is {new_vocab_size}; "
f"`max_tokens` is {self.max_tokens}."
)
self.lookup_table = self._lookup_table_from_tokens(tokens)
self._record_vocabulary_size()View on GitHub (pinned to 7a34a03db6)
Solutions
- Strip the oov token from the vocabulary before passing it.
- Or place it exactly at the reserved head position per the documented special-token order.
- Ensure encoder and decoder layers use consistent oov_token and num_oov_indices settings.
Example fix
# before inv_layer.set_vocabulary(vocab) # vocab includes '[UNK]' # after tokens = [t for t in vocab if t != '[UNK]'] inv_layer.set_vocabulary(tokens)
Defensive patterns
Strategy: validation
Validate before calling
vocab = [t for t in vocab if t != '[UNK]'] inv_layer.set_vocabulary(vocab)
Type guard
def free_of_oov(vocab, oov_token) -> bool:
return oov_token not in vocab Prevention
- Strip the oov token from decoder vocabularies; the layer reserves its own slot.
- Keep encoder and decoder special-token settings identical.
When it happens
Trigger: `layer.set_vocabulary(vocab)` on a layer with `invert=True` where vocab contains '[UNK]' at any position other than the reserved slot.
Common situations: Building a decoder lookup from a vocabulary file that already includes the '[UNK]' token.
Related errors
- Found reserved mask token at unexpected location in `vocabul
- Vocabulary file {vocabulary} does not exist.
- Cannot set an empty vocabulary. Received: vocabulary={vocabu
- The passed vocabulary has at least one repeated term. Please
- Attempted to set a vocabulary larger than the maximum vocab
AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25).
Data as JSON: /api/errors/b56000a3076f2222.
Report an issue: GitHub.