{"record":{"id":"16b03a8817e05356","repo":"Unity-Technologies/ml-agents","slug":"the-defaulttraininganalyticssidechannel-received-a","errorCode":null,"errorMessage":"The DefaultTrainingAnalyticsSideChannel received a message from Unity, this should not have happened.","messagePattern":"The DefaultTrainingAnalyticsSideChannel received a message from Unity, this should not have happened\\.","errorType":"exception","errorClass":"UnityCommunicationException","httpStatus":null,"severity":"error","filePath":"ml-agents-envs/mlagents_envs/side_channel/default_training_analytics_side_channel.py","lineNumber":28,"sourceCode":"from google.protobuf.any_pb2 import Any\n\n\nclass DefaultTrainingAnalyticsSideChannel(SideChannel):\n    \"\"\"\n    Side channel that sends information about the training to the Unity environment so it can be logged.\n    \"\"\"\n\n    CHANNEL_ID = uuid.UUID(\"b664a4a9-d86f-5a5f-95cb-e8353a7e8356\")\n\n    def __init__(self) -> None:\n        # >>> uuid.uuid5(uuid.NAMESPACE_URL, \"com.unity.ml-agents/TrainingAnalyticsSideChannel\")\n        # UUID('b664a4a9-d86f-5a5f-95cb-e8353a7e8356')\n        # We purposefully use the SAME side channel as the TrainingAnalyticsSideChannel\n\n        super().__init__(DefaultTrainingAnalyticsSideChannel.CHANNEL_ID)\n\n    def on_message_received(self, msg: IncomingMessage) -> None:\n        raise UnityCommunicationException(\n            \"The DefaultTrainingAnalyticsSideChannel received a message from Unity, \"\n            + \"this should not have happened.\"\n        )\n\n    def environment_initialized(self) -> None:\n        # Tuple of (major, minor, patch)\n        vi = sys.version_info\n\n        msg = TrainingEnvironmentInitialized(\n            python_version=f\"{vi[0]}.{vi[1]}.{vi[2]}\",\n            mlagents_version=\"Custom\",\n            mlagents_envs_version=mlagents_envs.__version__,\n            torch_version=\"Unknown\",\n            torch_device_type=\"Unknown\",\n        )\n        any_message = Any()\n        any_message.Pack(msg)\n","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/Unity-Technologies/ml-agents/blob/3ecb446f75d1e7400eb404c562dc005d3164cffc/ml-agents-envs/mlagents_envs/side_channel/default_training_analytics_side_channel.py#L10-L46","documentation":"DefaultTrainingAnalyticsSideChannel deliberately shares the TrainingAnalyticsSideChannel's UUID and is a Python-only placeholder: Unity should never send messages on this channel. Any incoming message means the Unity-side ML-Agents package is sending training analytics when the Python side expected none, so on_message_received raises UnityCommunicationException to signal a protocol mismatch.","triggerScenarios":"Calling env.step()/reset() while the attached Unity environment sends a message on channel UUID b664a4a9-d86f-5a5f-95cb-e8353a7e8356 (e.g. a Unity build built with TrainingAnalytics enabled) instead of the expected DefaultTrainingAnalyticsSideChannel.","commonSituations":"Running an older/newer Unity ML-Agents plugin against mismatched mlagents_envs Python package; using the default (no-analytics) channel with an editor build configured to send training analytics.","solutions":["Use the correct side channel: pass TrainingAnalyticsSideChannel (or construct the env so the matching channel is registered) instead of the default one.","Ensure Unity ML-Agents package and Python mlagents/mlagents_envs versions match (e.g. both release 18).","Rebuild/replace the Unity environment binary with one that does not send training analytics if you intend to use the default channel.","Wrap env communication in try/except UnityCommunicationException and log the Unity version for diagnosis."],"exampleFix":"// before\nenv = UnityEnvironment(file_name=env_path)\n// after\nfrom mlagents_envs.side_channel.training_analytics_side_channel import TrainingAnalyticsSideChannel\nanalytics = TrainingAnalyticsSideChannel()\nenv = UnityEnvironment(file_name=env_path, side_channels=[analytics])","handlingStrategy":"try-catch","validationCode":"from mlagents_envs.side_channel.training_analytics_side_channel import TrainingAnalyticsSideChannel\n# register the matching analytics channel so Unity's message is consumed, not rejected\nside_channels = [ch for ch in side_channels if not isinstance(ch, type(default_channel))]","typeGuard":null,"tryCatchPattern":"from mlagents_envs.exception import UnityCommunicationException\ntry:\n    env.step()\nexcept UnityCommunicationException as e:\n    print(\"Unity sent on a Python-only side channel; check ML-Agents version match:\", e)","preventionTips":["Keep Unity ML-Agents package and pip mlagents versions identical","Register TrainingAnalyticsSideChannel when the Unity build sends analytics","Don't send messages to Python-only side channels from custom Unity code","Test the env binary against your Python package version before long runs"],"tags":["unity","side-channel","version-mismatch"],"backgroundTag":"side-channel-version-mismatch","analyzedSha":"3ecb446f75d1e7400eb404c562dc005d3164cffc","analyzedAt":"2026-09-02T16:33:12.832Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}