Unity-Technologies/ml-agents · error · UnityEnvironmentException

There cannot be two side channels with the same channel id {

Error message

There cannot be two side channels with the same channel id {_sc.channel_id}.

What it means

SideChannelManager registers side channels in a dict keyed by channel_id; duplicate UUIDs would silently overwrite each other, so during construction (_get_side_channels_dict, called from __init__) a UnityEnvironmentException is raised if two channels share an id.

Source

Thrown at ml-agents-envs/mlagents_envs/side_channel/side_channel_manager.py:76

                result += channel_id.bytes_le
                result += struct.pack("<i", len(message))
                result += message
            channel.message_queue = []
        return result

    @staticmethod
    def _get_side_channels_dict(
        side_channels: Optional[List[SideChannel]],
    ) -> Dict[uuid.UUID, SideChannel]:
        """
        Converts a list of side channels into a dictionary of channel_id to SideChannel
        :param side_channels: The list of side channels.
        """
        side_channels_dict: Dict[uuid.UUID, SideChannel] = {}
        if side_channels is not None:
            for _sc in side_channels:
                if _sc.channel_id in side_channels_dict:
                    raise UnityEnvironmentException(
                        f"There cannot be two side channels with "
                        f"the same channel id {_sc.channel_id}."
                    )
                side_channels_dict[_sc.channel_id] = _sc
        return side_channels_dict

View on GitHub (pinned to 3ecb446f75)

Solutions

  1. Remove duplicate instances from the side_channels list before constructing UnityEnvironment.
  2. Reuse one channel instance everywhere instead of creating a second of the same class.
  3. Change the custom channel's channel_id to a fresh uuid.uuid4() if it collides with a built-in.
  4. Deduplicate defensively: pass list({c.channel_id: c for c in channels}.values()) into the env.

Example fix

// before
channels = [EngineConfigurationChannel(), EngineConfigurationChannel()]
env = UnityEnvironment(file_name=env_path, side_channels=channels)
// after
engine_channel = EngineConfigurationChannel()
env = UnityEnvironment(file_name=env_path, side_channels=[engine_channel])
Defensive patterns

Strategy: validation

Validate before calling

ids = [c.channel_id for c in side_channels]
assert len(ids) == len(set(ids)), f"duplicate side channel ids: {ids}"

Type guard

def no_duplicate_channels(channels):
    ids = [c.channel_id for c in channels]
    return len(ids) == len(set(ids))

Try / catch

from mlagents_envs.exception import UnityEnvironmentException
try:
    env = UnityEnvironment(file_name=path, side_channels=channels)
except UnityEnvironmentException as e:
    print("Deduplicate your side_channels list:", e)

Prevention

When it happens

Trigger: UnityEnvironment(..., side_channels=[a, b]) or SideChannelManager(side_channels=[...]) where two SideChannel instances return the same channel_id (e.g. two EngineConfigurationChannel instances, or a custom channel reusing a built-in UUID).

Common situations: Adding the same side-channel object twice to the list; instantiating two channels of the same class; custom channel accidentally copying a built-in channel id.

Related errors


AI-assisted analysis of Unity-Technologies/ml-agents@3ecb446f75 (2026-09-02). Data as JSON: /api/errors/7c43d35666b30aee. Report an issue: GitHub.