{"record":{"id":"6f267998143f928d","repo":"Unity-Technologies/ml-agents","slug":"a-side-channel-with-id-channelid-is-already-regi","errorCode":null,"errorMessage":"A side channel with id {channelId} is already registered. You cannot register multiple side channels of the same id.","messagePattern":"A side channel with id (.+?) is already registered\\. You cannot register multiple side channels of the same id\\.","errorType":"exception","errorClass":"UnityAgentsException","httpStatus":null,"severity":"error","filePath":"com.unity.ml-agents/Runtime/SideChannels/SideChannelManager.cs","lineNumber":44,"sourceCode":"        [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]\n        static void ResetStaticsOnLoad()\n        {\n            s_RegisteredChannels = new Dictionary<Guid, SideChannel>();\n        }\n#endif\n        /// <summary>\n        /// Register a side channel to begin sending and receiving messages. This method is\n        /// available for environments that have custom side channels. All built-in side\n        /// channels within the ML-Agents Toolkit are managed internally and do not need to\n        /// be explicitly registered/unregistered. A side channel may only be registered once.\n        /// </summary>\n        /// <param name=\"sideChannel\">The side channel to register.</param>\n        public static void RegisterSideChannel(SideChannel sideChannel)\n        {\n            var channelId = sideChannel.ChannelId;\n            if (s_RegisteredChannels.ContainsKey(channelId))\n            {\n                throw new UnityAgentsException(\n                    $\"A side channel with id {channelId} is already registered. \" +\n                    \"You cannot register multiple side channels of the same id.\");\n            }\n\n            // Process any messages that we've already received for this channel ID.\n            var numMessages = s_CachedMessages.Count;\n            for (var i = 0; i < numMessages; i++)\n            {\n                var cachedMessage = s_CachedMessages.Dequeue();\n                if (channelId == cachedMessage.ChannelId)\n                {\n                    sideChannel.ProcessMessage(cachedMessage.Message);\n                }\n                else\n                {\n                    s_CachedMessages.Enqueue(cachedMessage);\n                }\n            }","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/Unity-Technologies/ml-agents/blob/3ecb446f75d1e7400eb404c562dc005d3164cffc/com.unity.ml-agents/Runtime/SideChannels/SideChannelManager.cs#L26-L62","documentation":"SideChannelManager.RegisterSideChannel stores side channels by their UUID channel id in a single registry; each id may only be registered once. Registering a second SideChannel whose ChannelId GUID equals an existing one throws UnityAgentsException. This prevents messages from being ambiguously routed between channels.","triggerScenarios":"Calling RegisterSideChannel (or creating a UnityEnvironment/RpcCommunicator that auto-registers) with a side channel whose ChannelId GUID is already in s_RegisteredChannels — e.g. two instances of the same channel type, or a custom channel reusing a built-in's GUID.","commonSituations":"Adding the same StatsSideChannel/EngineConfigurationChannel instance twice; constructing two UnityEnvironment objects over the same registry and registering duplicate channels; copying a built-in channel class without changing its hardcoded ChannelId GUID.","solutions":["Register each channel id only once — keep a single shared instance of each channel type and reuse it.","Generate a unique GUID for your custom side channel (e.g. new System.Guid(\"...\") with a freshly generated value) instead of reusing one from another channel.","UnregisterSideChannel the old instance before registering a new one with the same id, if replacement is intended."],"exampleFix":"// before\nvar stats1 = new StatsSideChannel();\nvar stats2 = new StatsSideChannel(); // same ChannelId GUID\nSideChannelManager.RegisterSideChannel(stats1);\nSideChannelManager.RegisterSideChannel(stats2); // throws\n// after\nvar stats = new StatsSideChannel();\nSideChannelManager.RegisterSideChannel(stats); // one instance only","handlingStrategy":"validation","validationCode":"// C#\nif (SideChannelManager.GetSideChannelIds().Contains(myChannel.ChannelId))\n    return; // already registered\n","typeGuard":null,"tryCatchPattern":"try { SideChannelManager.RegisterSideChannel(channel); }\ncatch (UnityAgentsException e) { Debug.LogWarning($\"Channel {channel.ChannelId} already registered\"); }","preventionTips":["Keep one shared instance per channel type","Give custom channels freshly generated unique GUIDs","Unregister before re-registering on teardown/restart"],"tags":["unity","ml-agents","side-channel","duplicate-registration","guid"],"backgroundTag":"duplicate-key-registration","analyzedSha":"3ecb446f75d1e7400eb404c562dc005d3164cffc","analyzedAt":"2026-09-02T16:33:12.832Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}