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
- Wrap plain strings in the proper key class, e.g. AgentGroupKey or ObservationKeyPrefix-based keys
- Check CHECK_KEY_TYPES_AT_RUNTIME usage and construct keys via the library's factory functions
- 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
- Never pass bare strings or dicts as buffer keys
- Convert legacy string keys via AgentBuffer._decode_key
- Wrap buffer access in a helper that validates keys once
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
- {key} has type ({type(key0)}, {type(key1)})
- 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/6546961f7910b3e3.
Report an issue: GitHub.