Unity-Technologies/ml-agents · error · NotImplementedError

NotImplementedError

Error message

NotImplementedError

What it means

Trainer.get_trainer_name is an abstract static method that unconditionally raises NotImplementedError. Every concrete trainer class (PPOTrainer, SACTrainer, GhostTrainer, OnlineBCTrainer) must override it to return its name; hitting this error means code invoked the base class implementation directly.

Source

Thrown at ml-agents/mlagents/trainers/trainer/trainer.py:183

        """
        Adds a policy queue to the list of queues to publish to when this Trainer
        makes a policy update
        :param policy_queue: Policy queue to publish to.
        """
        self.policy_queues.append(policy_queue)

    def subscribe_trajectory_queue(
        self, trajectory_queue: AgentManagerQueue[Trajectory]
    ) -> None:
        """
        Adds a trajectory queue to the list of queues for the trainer to ingest Trajectories from.
        :param trajectory_queue: Trajectory queue to read from.
        """
        self.trajectory_queues.append(trajectory_queue)

    @staticmethod
    def get_trainer_name() -> str:
        raise NotImplementedError

View on GitHub (pinned to 3ecb446f75)

Solutions

  1. Override get_trainer_name in your custom trainer subclass and return its unique string name
  2. Do not instantiate the base Trainer class directly; use a concrete trainer from TrainerFactory
  3. Register your trainer in the trainer_type dict used by TrainerFactory so the correct class is constructed
  4. Update ML-Agents if a built-in trainer is missing the override (should not occur in released versions)

Example fix

// before
class MyTrainer(Trainer):
    pass
// after
class MyTrainer(Trainer):
    @staticmethod
    def get_trainer_name() -> str:
        return "my_trainer"
Defensive patterns

Strategy: validation

Validate before calling

import inspect
from mlagents.trainers.trainer.trainer import Trainer
assert not (inspect.isclass(MyTrainer) and issubclass(MyTrainer, Trainer)) or MyTrainer.get_trainer_name is not Trainer.get_trainer_name, "Must override get_trainer_name"

Type guard

def overrides_get_trainer_name(cls) -> bool:
    return cls.get_trainer_name.__func__ is not Trainer.get_trainer_name.__func__ if hasattr(cls.get_trainer_name, '__func__') else cls.get_trainer_name is not Trainer.get_trainer_name

Try / catch

try:
    name = trainer_cls.get_trainer_name()
except NotImplementedError:
    raise RuntimeError(f"{trainer_cls.__name__} must implement get_trainer_name()")

Prevention

When it happens

Trigger: Calling get_trainer_name on a subclass that forgot to override it, or instantiating/using the abstract base Trainer directly instead of a concrete trainer.

Common situations: Writing a custom trainer subclass that doesn't override get_trainer_name; refactorings that register a trainer with the TrainerFactory while the class is missing the override; calling the method on the base class in tests or tooling.

Related errors


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