Unity-Technologies/ml-agents · error · KeyError

{key} is a {type(key)}

Error message

{key} is a {type(key)}

What it means

The final fallback branch of AgentBuffer._check_key: the key is neither a valid tuple nor a recognized key type, so this KeyError is raised reporting the key's type. All buffer accessors route through this validation when CHECK_KEY_TYPES_AT_RUNTIME is enabled.

Source

Thrown at ml-agents/mlagents/trainers/buffer.py:297

            f.reset_field()
        self.last_brain_info = None
        self.last_take_action_outputs = None

    @staticmethod
    def _check_key(key):
        if isinstance(key, BufferKey):
            return
        if isinstance(key, tuple):
            key0, key1 = key
            if isinstance(key0, ObservationKeyPrefix):
                if isinstance(key1, int):
                    return
                raise KeyError(f"{key} has type ({type(key0)}, {type(key1)})")
            if isinstance(key0, RewardSignalKeyPrefix):
                if isinstance(key1, str):
                    return
                raise KeyError(f"{key} has type ({type(key0)}, {type(key1)})")
        raise KeyError(f"{key} is a {type(key)}")

    @staticmethod
    def _encode_key(key: AgentBufferKey) -> str:
        """
        Convert the key to a string representation so that it can be used for serialization.
        """
        if isinstance(key, BufferKey):
            return key.value
        prefix, suffix = key
        return f"{prefix.value}:{suffix}"

    @staticmethod
    def _decode_key(encoded_key: str) -> AgentBufferKey:
        """
        Convert the string representation back to a key after serialization.
        """
        # Simple case: convert the string directly to a BufferKey
        try:

View on GitHub (pinned to 3ecb446f75)

Solutions

  1. Wrap plain strings in the proper key class, e.g. AgentGroupKey or ObservationKeyPrefix-based keys
  2. Check CHECK_KEY_TYPES_AT_RUNTIME usage and construct keys via the library's factory functions
  3. Convert serialized strings back with AgentBuffer._decode_key before use

Example fix

// before
field = buffer['VectorObservation']
// after
from mlagents.trainers.buffer import AgentBuffer
field = buffer[(ObservationKeyPrefix('VectorObservation'), 0)]
Defensive patterns

Strategy: type-guard

Validate before calling

def is_agent_buffer_key(key):
    if isinstance(key, tuple) and len(key) == 2:
        k0, k1 = key
        if isinstance(k0, ObservationKeyPrefix):
            return isinstance(k1, int)
        if isinstance(k0, RewardSignalKeyPrefix):
            return isinstance(k1, str)
    return False
if not is_agent_buffer_key(key): raise TypeError(key)

Type guard

def is_agent_buffer_key(key) -> bool:
    if isinstance(key, tuple) and len(key) == 2:
        k0, k1 = key
        return (isinstance(k0, ObservationKeyPrefix) and isinstance(k1, int)) or \
               (isinstance(k0, RewardSignalKeyPrefix) and isinstance(k1, str))
    return False

Try / catch

try:
    field = buffer[key]
except KeyError:
    raise TypeError(f"{key!r} is not a valid AgentBufferKey; use key classes from mlagents.trainers.buffer")

Prevention

When it happens

Trigger: Passing a bare string, list, or any non-tuple object as an AgentBufferKey to __getitem__, __setitem__, __delitem__, __contains__ or check_length — e.g. buffer['VectorObservation'] instead of a key object.

Common situations: Treating the buffer like a plain dict of column-name strings, migrating code from older ml-agents versions where string keys were accepted, or loading keys from JSON/YAML without conversion.

Related errors


AI-assisted analysis of Unity-Technologies/ml-agents@3ecb446f75 (2026-09-02). Data as JSON: /api/errors/6546961f7910b3e3. Report an issue: GitHub.