Unity-Technologies/ml-agents · error · UnityGymException

There can only be one Agent in the environment but {n_agents

Error message

There can only be one Agent in the environment but {n_agents} were detected.

What it means

Static UnityGymEnv._check_agents raises UnityGymException when the environment reports more than one Agent in the single behavior. The gym wrapper is strictly single-agent, matching gym's observation/action space contract.

Source

Thrown at ml-agents-envs/mlagents_envs/envs/unity_gym_env.py:319

    def close(self) -> None:
        """Override _close in your subclass to perform any necessary cleanup.
        Environments will automatically close() themselves when
        garbage collected or when the program exits.
        """
        self._env.close()

    def seed(self, seed: Any = None) -> None:
        """Sets the seed for this env's random number generator(s).
        Currently not implemented.
        """
        logger.warning("Could not seed environment %s", self.name)
        return

    @staticmethod
    def _check_agents(n_agents: int) -> None:
        if n_agents > 1:
            raise UnityGymException(
                f"There can only be one Agent in the environment but {n_agents} were detected."
            )

    @property
    def metadata(self):
        return {"render_modes": ["rgb_array"]}

    @property
    def reward_range(self) -> Tuple[float, float]:
        return -float("inf"), float("inf")

    @property
    def action_space(self) -> gym.Space:
        return self._action_space

    @property
    def observation_space(self):
        return self._observation_space

View on GitHub (pinned to 3ecb446f75)

Solutions

  1. Ensure exactly one Agent (per behavior) exists in the Unity scene and rebuild.
  2. Remove extra Agents or move them to a separate behavior (which then trips error 50 — so use the raw UnityEnvironment API instead for multi-agent).
  3. Use mlagents-envs UnityEnvironment directly; DecisionSteps supports N agents natively.
  4. If agents spawn dynamically, gate spawning so total count stays at 1.

Example fix

// before
# Scene: 3 Agents with behavior "MyBehavior"
env = UnityGymEnv(UnityEnvironment(file_name='multi_agent_app'))
// after
# Scene: 1 Agent with behavior "MyBehavior"
env = UnityGymEnv(UnityEnvironment(file_name='single_agent_app'))
# or for multi-agent: unity_env = UnityEnvironment(...); use unity_env.get_steps("MyBehavior")
Defensive patterns

Strategy: validation

Validate before calling

unity_env.reset()
decs, _ = unity_env.get_steps(behavior_name)
if len(decs.agent_id) > 1:
    raise ValueError(f"Gym wrapper needs exactly 1 agent, found {len(decs.agent_id)}")
env = UnityGymEnv(unity_env)

Type guard

def is_single_agent(steps) -> bool:
    return len(steps.agent_id) == 1

Try / catch

try:
    obs = env.reset()
except UnityGymException:
    raise RuntimeError("Multiple agents detected; use UnityEnvironment API for multi-agent scenes")

Prevention

When it happens

Trigger: Called from __init__, reset(), and step() with the number of detected agents (len of agent_ids in DecisionSteps/TerminalSteps) greater than 1.

Common situations: Unity scene with multiple Agents sharing one Behavior name; population-based or multi-agent training scenes; environment spawns a second Agent mid-episode, so the error fires during step/reset rather than at construction.

Related errors


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