{"record":{"id":"c970d768c501c971","repo":"Unity-Technologies/ml-agents","slug":"notimplementederror","errorCode":null,"errorMessage":"NotImplementedError","messagePattern":"NotImplementedError","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"ml-agents/mlagents/trainers/trainer/trainer.py","lineNumber":183,"sourceCode":"        \"\"\"\n        Adds a policy queue to the list of queues to publish to when this Trainer\n        makes a policy update\n        :param policy_queue: Policy queue to publish to.\n        \"\"\"\n        self.policy_queues.append(policy_queue)\n\n    def subscribe_trajectory_queue(\n        self, trajectory_queue: AgentManagerQueue[Trajectory]\n    ) -> None:\n        \"\"\"\n        Adds a trajectory queue to the list of queues for the trainer to ingest Trajectories from.\n        :param trajectory_queue: Trajectory queue to read from.\n        \"\"\"\n        self.trajectory_queues.append(trajectory_queue)\n\n    @staticmethod\n    def get_trainer_name() -> str:\n        raise NotImplementedError\n","sourceCodeStart":165,"sourceCodeEnd":184,"githubUrl":"https://github.com/Unity-Technologies/ml-agents/blob/3ecb446f75d1e7400eb404c562dc005d3164cffc/ml-agents/mlagents/trainers/trainer/trainer.py#L165-L184","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Override get_trainer_name in your custom trainer subclass and return its unique string name","Do not instantiate the base Trainer class directly; use a concrete trainer from TrainerFactory","Register your trainer in the trainer_type dict used by TrainerFactory so the correct class is constructed","Update ML-Agents if a built-in trainer is missing the override (should not occur in released versions)"],"exampleFix":"// before\nclass MyTrainer(Trainer):\n    pass\n// after\nclass MyTrainer(Trainer):\n    @staticmethod\n    def get_trainer_name() -> str:\n        return \"my_trainer\"","handlingStrategy":"validation","validationCode":"import inspect\nfrom mlagents.trainers.trainer.trainer import Trainer\nassert not (inspect.isclass(MyTrainer) and issubclass(MyTrainer, Trainer)) or MyTrainer.get_trainer_name is not Trainer.get_trainer_name, \"Must override get_trainer_name\"","typeGuard":"def overrides_get_trainer_name(cls) -> bool:\n    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","tryCatchPattern":"try:\n    name = trainer_cls.get_trainer_name()\nexcept NotImplementedError:\n    raise RuntimeError(f\"{trainer_cls.__name__} must implement get_trainer_name()\")","preventionTips":["Always override get_trainer_name in custom trainer subclasses","Never instantiate the base Trainer directly","Register custom trainers with TrainerFactory under a unique name"],"tags":["python","mlagents","abstract-method","custom-trainer"],"backgroundTag":"notimplemented-abstract-method","analyzedSha":"3ecb446f75d1e7400eb404c562dc005d3164cffc","analyzedAt":"2026-09-02T16:33:12.832Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}