{"record":{"id":"60077c924c334130","repo":"Unity-Technologies/ml-agents","slug":"the-traininganalyticssidechannel-received-a-messag","errorCode":null,"errorMessage":"The TrainingAnalyticsSideChannel received a message from Unity, this should not have happened.","messagePattern":"The TrainingAnalyticsSideChannel received a message from Unity, this should not have happened\\.","errorType":"exception","errorClass":"UnityCommunicationException","httpStatus":null,"severity":"error","filePath":"ml-agents/mlagents/trainers/training_analytics_side_channel.py","lineNumber":48,"sourceCode":"\n    __vendorKey: str = \"unity.ml-agents\"\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        # Use the same uuid as the parent side channel\n        super().__init__()\n        self.run_options: Optional[RunOptions] = None\n\n    @classmethod\n    def _hash(cls, data: str) -> str:\n        res = hmac.new(\n            cls.__vendorKey.encode(\"utf-8\"), data.encode(\"utf-8\"), hashlib.sha256\n        ).hexdigest()\n        return res\n\n    def on_message_received(self, msg: IncomingMessage) -> None:\n        raise UnityCommunicationException(\n            \"The TrainingAnalyticsSideChannel received a message from Unity, \"\n            \"this should not have happened.\"\n        )\n\n    @classmethod\n    def _sanitize_run_options(cls, config: RunOptions) -> Dict[str, Any]:\n        res = copy.deepcopy(config.as_dict())\n\n        # Filter potentially PII behavior names\n        if \"behaviors\" in res and res[\"behaviors\"]:\n            res[\"behaviors\"] = {cls._hash(k): v for (k, v) in res[\"behaviors\"].items()}\n            for (k, v) in res[\"behaviors\"].items():\n                if \"init_path\" in v and v[\"init_path\"] is not None:\n                    hashed_path = cls._hash(v[\"init_path\"])\n                    res[\"behaviors\"][k][\"init_path\"] = hashed_path\n                if \"demo_path\" in v and v[\"demo_path\"] is not None:\n                    hashed_path = cls._hash(v[\"demo_path\"])\n                    res[\"behaviors\"][k][\"demo_path\"] = hashed_path","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/Unity-Technologies/ml-agents/blob/3ecb446f75d1e7400eb404c562dc005d3164cffc/ml-agents/mlagents/trainers/training_analytics_side_channel.py#L30-L66","documentation":"TrainingAnalyticsSideChannel.on_message_received unconditionally raises UnityCommunicationException. This side channel is one-way (trainer sends analytics to Unity) and the Unity side should never send messages back; receiving one signals a protocol/communication error between the editor and the trainer process.","triggerScenarios":"Unity sending a message on the TrainingAnalytics side channel, e.g. due to a mismatched or buggy side-channel implementation in the ml-agents-envs/commlabels versions, or custom editor code writing to the same channel UUID.","commonSituations":"Version mismatch between the ml-agents Python package and the com.unity.ml-agents Unity package; a custom fork or plugin reusing the analytics channel GUID; corrupted inter-process communication.","solutions":["Align versions of the Python mlagents package and the Unity com.unity.ml-agents package (check release compatibility table)","Remove any custom code sending messages on the TrainingAnalytics channel GUID","Disable the training analytics side channel (e.g. via --no-graphics / analytics-related flags) if not needed","Reinstall matching mlagents/mlagents_envs versions (pip install mlagents==<matching version>)"],"exampleFix":"// before (custom code on analytics channel)\nside_channel_manager.send_message(training_analytics_channel, msg)\n// after\n# remove the send; analytics channel is one-way (trainer -> Unity)","handlingStrategy":"try-catch","validationCode":"import mlagents, importlib.metadata\nprint(importlib.metadata.version(\"mlagents\"))\n# Ensure this matches the com.unity.ml-agents package version in Unity","typeGuard":null,"tryCatchPattern":"from mlagents_envs.exception import UnityCommunicationException\ntry:\n    env.step()  # any side-channel message handling\nexcept UnityCommunicationException as e:\n    if \"TrainingAnalyticsSideChannel\" in str(e):\n        logger.warning(\"Unity sent an unexpected analytics message; check package version match\")\n    else:\n        raise","preventionTips":["Keep mlagents Python package and com.unity.ml-agents Unity package on matching versions","Never send messages from Unity on one-way (trainer-to-Unity) side channels","Do not reuse the TrainingAnalytics channel UUID for custom side channels","Update both sides together when upgrading ML-Agents"],"tags":["python","mlagents","side-channel","version-mismatch","communication"],"backgroundTag":"side-channel-protocol-violation","analyzedSha":"3ecb446f75d1e7400eb404c562dc005d3164cffc","analyzedAt":"2026-09-02T16:33:12.832Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}