{"record":{"id":"71118d76da2fb196","repo":"Unity-Technologies/ml-agents","slug":"key-has-type-type-key0-type-key1","errorCode":null,"errorMessage":"{key} has type ({type(key0)}, {type(key1)})","messagePattern":"(.+?) has type \\((.+?), (.+?)\\)","errorType":"exception","errorClass":"KeyError","httpStatus":null,"severity":"error","filePath":"ml-agents/mlagents/trainers/buffer.py","lineNumber":292,"sourceCode":"    def reset_agent(self) -> None:\n        \"\"\"\n        Resets the AgentBuffer\n        \"\"\"\n        for f in self._fields.values():\n            f.reset_field()\n        self.last_brain_info = None\n        self.last_take_action_outputs = None\n\n    @staticmethod\n    def _check_key(key):\n        if isinstance(key, BufferKey):\n            return\n        if isinstance(key, tuple):\n            key0, key1 = key\n            if isinstance(key0, ObservationKeyPrefix):\n                if isinstance(key1, int):\n                    return\n                raise KeyError(f\"{key} has type ({type(key0)}, {type(key1)})\")\n            if isinstance(key0, RewardSignalKeyPrefix):\n                if isinstance(key1, str):\n                    return\n                raise KeyError(f\"{key} has type ({type(key0)}, {type(key1)})\")\n        raise KeyError(f\"{key} is a {type(key)}\")\n\n    @staticmethod\n    def _encode_key(key: AgentBufferKey) -> str:\n        \"\"\"\n        Convert the key to a string representation so that it can be used for serialization.\n        \"\"\"\n        if isinstance(key, BufferKey):\n            return key.value\n        prefix, suffix = key\n        return f\"{prefix.value}:{suffix}\"\n\n    @staticmethod\n    def _decode_key(encoded_key: str) -> AgentBufferKey:","sourceCodeStart":274,"sourceCodeEnd":310,"githubUrl":"https://github.com/Unity-Technologies/ml-agents/blob/3ecb446f75d1e7400eb404c562dc005d3164cffc/ml-agents/mlagents/trainers/buffer.py#L274-L310","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nkey = (ObservationKeyPrefix('VectorObservation'), '3')\nfield = buffer[key]\n// after\nkey = (ObservationKeyPrefix('VectorObservation'), 3)\nfield = buffer[key]","handlingStrategy":"type-guard","validationCode":"def is_valid_buffer_key(key):\n    if isinstance(key, tuple) and len(key) == 2:\n        k0, k1 = key\n        if isinstance(k0, ObservationKeyPrefix):\n            return isinstance(k1, int)\n        if isinstance(k0, RewardSignalKeyPrefix):\n            return isinstance(k1, str)\n    return False\n# call buffer ops only if is_valid_buffer_key(key)","typeGuard":"def is_obs_key(key) -> bool:\n    return (isinstance(key, tuple) and len(key) == 2\n            and isinstance(key[0], ObservationKeyPrefix)\n            and isinstance(key[1], int))","tryCatchPattern":"try:\n    field = buffer[key]\nexcept KeyError as e:\n    logger.error(f\"Invalid buffer key {key}: {e}\")\n    field = None","preventionTips":["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"],"tags":["keyerror","type-mismatch","ml-agents","buffer"],"backgroundTag":"invalid-buffer-key-type","analyzedSha":"3ecb446f75d1e7400eb404c562dc005d3164cffc","analyzedAt":"2026-09-02T16:33:12.832Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}