{"record":{"id":"e7484c40f5a759ba","repo":"Unity-Technologies/ml-agents","slug":"decompressed-observation-did-not-have-the-expected","errorCode":null,"errorMessage":"Decompressed observation did not have the expected shape - decompressed had {img.shape} but expected {obs.shape}","messagePattern":"Decompressed observation did not have the expected shape - decompressed had (.+?) but expected (.+?)","errorType":"exception","errorClass":"UnityObservationException","httpStatus":null,"severity":"error","filePath":"ml-agents-envs/mlagents_envs/rpc_utils.py","lineNumber":241,"sourceCode":"    :return: processed numpy array of observation from environment\n    \"\"\"\n    if expected_shape is not None:\n        if list(obs.shape) != list(expected_shape):\n            raise UnityObservationException(\n                f\"Observation did not have the expected shape - got {obs.shape} but expected {expected_shape}\"\n            )\n    expected_channels = obs.shape[0]\n    if obs.compression_type == COMPRESSION_TYPE_NONE:\n        img = np.array(obs.float_data.data, dtype=np.float32)\n        img = np.reshape(img, obs.shape)\n        return img\n    else:\n        img = process_pixels(\n            obs.compressed_data, expected_channels, list(obs.compressed_channel_mapping)\n        )\n        # Compare decompressed image size to observation shape and make sure they match\n        if list(obs.shape) != list(img.shape):\n            raise UnityObservationException(\n                f\"Decompressed observation did not have the expected shape - \"\n                f\"decompressed had {img.shape} but expected {obs.shape}\"\n            )\n        return img\n\n\n@timed\ndef _process_maybe_compressed_observation(\n    obs_index: int,\n    observation_spec: ObservationSpec,\n    agent_info_list: Collection[AgentInfoProto],\n) -> np.ndarray:\n    shape = cast(Tuple[int, int, int], observation_spec.shape)\n    if len(agent_info_list) == 0:\n        return np.zeros((0, shape[0], shape[1], shape[2]), dtype=np.float32)\n\n    try:\n        batched_visual = [","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/Unity-Technologies/ml-agents/blob/3ecb446f75d1e7400eb404c562dc005d3164cffc/ml-agents-envs/mlagents_envs/rpc_utils.py#L223-L259","documentation":"UnityObservationException raised by _observation_to_np_array after decompressing a compressed observation: the reconstructed numpy image's shape doesn't match obs.shape declared in the proto. It means Unity's compressed payload (e.g. PNG) doesn't decode to the dimensions it claims.","triggerScenarios":"process_pixels decompressing obs.compressed_data into an image whose shape != obs.shape — e.g. PNG bytes with different width/height/channels than declared, often from version-skewed serialization or corrupted data.","commonSituations":"Mismatched ml-agents Unity/Python versions changing compression conventions; camera resolution changed in Unity without relaunching the env; corrupted image data over gRPC; custom grab implementations sending wrong-size frames.","solutions":["Match com.unity.ml-agents and mlagents-envs versions and rebuild the Unity executable.","Restart UnityEnvironment after changing camera resolutions or sensor setups in the editor.","Verify with a stock sample environment to rule out environment-specific corruption.","Check that no custom Unity-side code overrides the camera grab dimensions (CameraSensor width/height must match ObservationSpec)."],"exampleFix":"// before\n# camera resolution changed in editor; old env still running\nimg_shape = (3, 84, 84); declared = (3, 96, 96)\n// after\nenv.close(); env = UnityEnvironment(...)  # spec and pixels agree","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"from mlagents_envs.exception import UnityObservationException\n\ntry:\n    env.step()\nexcept UnityObservationException as e:\n    if \"Decompressed observation\" in str(e):\n        env.close()\n        env = UnityEnvironment(file_name=env_path)  # refresh spec; verify versions","preventionTips":["Match Unity/Python ml-agents versions; rebuild after upgrades.","Relaunch the env after camera resolution changes.","Confirm camera sensor width/height in Unity match expected ObservationSpec.","Sanity-check with a sample environment to rule out data corruption."],"tags":["python","unity-ml-agents","observation","compression","shape-mismatch"],"backgroundTag":"observation-shape-mismatch","analyzedSha":"3ecb446f75d1e7400eb404c562dc005d3164cffc","analyzedAt":"2026-09-02T16:33:12.832Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}