Unity-Technologies/ml-agents · error · KeyError

{key} has type ({type(key0)}, {type(key1)})

Error message

{key} has type ({type(key0)}, {type(key1)})

What it means

AgentBuffer._check_key validates that tuple keys have well-typed components. An ObservationKeyPrefix must be paired with an int index; anything else raises this KeyError. The message shows the actual types of both tuple elements so you can see which one is wrong.

Source

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

    def reset_agent(self) -> None:
        """
        Resets the AgentBuffer
        """
        for f in self._fields.values():
            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:

View on GitHub (pinned to 3ecb446f75)

Solutions

  1. Use the key factory helpers (AgentBufferField keys like ObsGroupKey / ObservationKeyPrefix(name, int_index)) instead of building tuples manually
  2. Ensure the second element of the tuple with an ObservationKeyPrefix is an int (e.g. int(suffix))
  3. If the key came from a string, decode it with AgentBuffer._decode_key rather than splitting it yourself

Example fix

// before
key = (ObservationKeyPrefix('VectorObservation'), '3')
field = buffer[key]
// after
key = (ObservationKeyPrefix('VectorObservation'), 3)
field = buffer[key]
Defensive patterns

Strategy: type-guard

Validate before calling

def is_valid_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
# call buffer ops only if is_valid_buffer_key(key)

Type guard

def is_obs_key(key) -> bool:
    return (isinstance(key, tuple) and len(key) == 2
            and isinstance(key[0], ObservationKeyPrefix)
            and isinstance(key[1], int))

Try / catch

try:
    field = buffer[key]
except KeyError as e:
    logger.error(f"Invalid buffer key {key}: {e}")
    field = None

Prevention

When it happens

Trigger: Indexing an AgentBuffer with a tuple like (ObservationKeyPrefix('VectorObservation'), 'not-an-int') via __getitem__, __setitem__, __delitem__, __contains__ or check_length, e.g. buffer[ObsGroupKey('name', '0')] or passing a str suffix instead of int.

Common situations: Hand-constructing buffer keys after a refactor, deserializing keys from a saved file without _decode_key, or mixing up the int suffix of ObservationKeyPrefix keys with the str suffix of RewardSignalKeyPrefix keys.

Related errors


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