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
- Use the key factory helpers (AgentBufferField keys like ObsGroupKey / ObservationKeyPrefix(name, int_index)) instead of building tuples manually
- Ensure the second element of the tuple with an ObservationKeyPrefix is an int (e.g. int(suffix))
- 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
- Always construct keys with the library's key classes, not raw tuples
- Remember: ObservationKeyPrefix pairs with int, RewardSignalKeyPrefix pairs with str
- Use AgentBuffer._decode_key for string-encoded keys instead of manual parsing
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
- {key} is a {type(key)}
- agent_id {agent_id} is not present in the DecisionSteps
- agent_id {agent_id} is not present in the TerminalSteps
- Unable to convert {encoded_key} to an AgentBufferKey
- Unable to shuffle if the fields are not of same length
AI-assisted analysis of Unity-Technologies/ml-agents@3ecb446f75 (2026-09-02).
Data as JSON: /api/errors/71118d76da2fb196.
Report an issue: GitHub.