{"record":{"id":"eb592bc540dcbc06","repo":"Unity-Technologies/ml-agents","slug":"compressed-observation-and-its-mapping-had-differe","errorCode":null,"errorMessage":"Compressed observation and its mapping had different number of channels - observation had {len(image_arrays)} channels but its mapping had {len(mappings)} channels","messagePattern":"Compressed observation and its mapping had different number of channels - observation had (.+?) channels but its mapping had (.+?) channels","errorType":"exception","errorClass":"UnityObservationException","httpStatus":null,"severity":"error","filePath":"ml-agents-envs/mlagents_envs/rpc_utils.py","lineNumber":150,"sourceCode":"            image_fp.offset = new_offset\n        except ValueError:\n            # Didn't find the header, so must be at the end.\n            break\n\n    if mappings is not None and len(mappings) > 0:\n        return _process_images_mapping(image_arrays, mappings)\n    else:\n        return _process_images_num_channels(image_arrays, expected_channels)\n\n\ndef _process_images_mapping(image_arrays, mappings):\n    \"\"\"\n    Helper function for processing decompressed images with compressed channel mappings.\n    \"\"\"\n    image_arrays = np.concatenate(image_arrays, axis=0).transpose((0, 1, 2))\n\n    if len(mappings) != len(image_arrays):\n        raise UnityObservationException(\n            f\"Compressed observation and its mapping had different number of channels - \"\n            f\"observation had {len(image_arrays)} channels but its mapping had {len(mappings)} channels\"\n        )\n    if len({m for m in mappings if m > -1}) != max(mappings) + 1:\n        raise UnityObservationException(\n            f\"Invalid Compressed Channel Mapping: the mapping {mappings} does not have the correct format.\"\n        )\n    if max(mappings) >= len(image_arrays):\n        raise UnityObservationException(\n            f\"Invalid Compressed Channel Mapping: the mapping has index larger than the total \"\n            f\"number of channels in observation - mapping index {max(mappings)} is\"\n            f\"invalid for input observation with {len(image_arrays)} channels.\"\n        )\n\n    processed_image_arrays: List[np.array] = [[] for _ in range(max(mappings) + 1)]\n    for mapping_idx, img in zip(mappings, image_arrays):\n        if mapping_idx > -1:\n            processed_image_arrays[mapping_idx].append(img)","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/Unity-Technologies/ml-agents/blob/3ecb446f75d1e7400eb404c562dc005d3164cffc/ml-agents-envs/mlagents_envs/rpc_utils.py#L132-L168","documentation":"UnityObservationException thrown by _process_images_mapping when the number of decompressed image channels (from the compressed observation payload) differs from the number of entries in compressed_channel_mapping sent by Unity. The mapping array and the image stack must be the same length so each channel can be reassembled.","triggerScenarios":"process_pixels receiving compressed_data whose decompressed channel count != len(compressed_channel_mapping) — i.e. Unity sent a channel mapping inconsistent with the compressed observation.","commonSituations":"Mismatched Unity/Python ml-agents versions producing inconsistent observation protos; custom or modified Unity observation code emitting wrong channel mappings; corrupted serialization of the message.","solutions":["Verify the com.unity.ml-agents package version in Unity matches the ml-agents-envs Python package version and upgrade both to the same release.","Rebuild the Unity executable after any change to agents/cameras so observations and channel mappings stay consistent.","Reduce observation complexity (e.g. grayscale) to rule out custom sensor issues, then re-enable components to isolate the mismatching source."],"exampleFix":"// before\n# Unity env built from an older/ml-agents mismatched version\n# after\n# pip install mlagents==0.30.0 mlagents-envs==0.30.0 and rebuild the executable with matching com.unity.ml-agents 0.30.0","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"from mlagents_envs.exception import UnityObservationException\n\ntry:\n    env.step()\nexcept UnityObservationException as e:\n    print(\"Observation/channel mapping mismatch:\", e)\n    env.close()\n    env = UnityEnvironment(file_name=env_path)  # relaunch with matched versions","preventionTips":["Keep the Unity package and Python packages on identical release versions.","Rebuild the executable after any Unity-side changes.","Test with a sample environment after upgrading either side."],"tags":["python","unity-ml-agents","observation","protocol-mismatch"],"backgroundTag":"observation-channel-mapping-mismatch","analyzedSha":"3ecb446f75d1e7400eb404c562dc005d3164cffc","analyzedAt":"2026-09-02T16:33:12.832Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}