{"record":{"id":"4e58f31e2d586d64","repo":"Unity-Technologies/ml-agents","slug":"config-doesn-t-specify-a-trainer-type-please-spec","errorCode":null,"errorMessage":"Config doesn't specify a trainer type. Please specify trainer: in your config.","messagePattern":"Config doesn't specify a trainer type\\. Please specify trainer: in your config\\.","errorType":"exception","errorClass":"TrainerConfigError","httpStatus":null,"severity":"error","filePath":"ml-agents/mlagents/trainers/upgrade_config.py","lineNumber":30,"sourceCode":"from mlagents.trainers.exception import TrainerConfigError\nfrom mlagents.plugins import all_trainer_settings\n\n\n# Take an existing trainer config (e.g. trainer_config.yaml) and turn it into the new format.\ndef convert_behaviors(old_trainer_config: Dict[str, Any]) -> Dict[str, Any]:\n    all_behavior_config_dict = {}\n    default_config = old_trainer_config.get(\"default\", {})\n    for behavior_name, config in old_trainer_config.items():\n        if behavior_name != \"default\":\n            config = default_config.copy()\n            config.update(old_trainer_config[behavior_name])\n\n            # Convert to split TrainerSettings, Hyperparameters, NetworkSettings\n            # Set trainer_type and get appropriate hyperparameter settings\n            try:\n                trainer_type = config[\"trainer\"]\n            except KeyError:\n                raise TrainerConfigError(\n                    \"Config doesn't specify a trainer type. \"\n                    \"Please specify trainer: in your config.\"\n                )\n            new_config = {}\n            new_config[\"trainer_type\"] = trainer_type\n            hyperparam_cls = all_trainer_settings[trainer_type]\n            # Try to absorb as much as possible into the hyperparam_cls\n            new_config[\"hyperparameters\"] = cattr.structure(config, hyperparam_cls)\n\n            # Try to absorb as much as possible into the network settings\n            new_config[\"network_settings\"] = cattr.structure(config, NetworkSettings)\n            # Deal with recurrent\n            try:\n                if config[\"use_recurrent\"]:\n                    new_config[\n                        \"network_settings\"\n                    ].memory = NetworkSettings.MemorySettings(\n                        sequence_length=config[\"sequence_length\"],","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/Unity-Technologies/ml-agents/blob/3ecb446f75d1e7400eb404c562dc005d3164cffc/ml-agents/mlagents/trainers/upgrade_config.py#L12-L48","documentation":"upgrade_config.convert_behaviors() converts an old single-section YAML config into the newer per-behavior TrainerSettings/Hyperparameters/NetworkSettings format. It reads config[\"trainer\"] to determine which hyperparameter class to use; a missing 'trainer' key means the legacy config doesn't say which trainer (ppo, sac, poca) it targets, so a TrainerConfigError is raised.","triggerScenarios":"Running `mlagents-learn --convert-to-config` (which calls convert) on a legacy config YAML whose top-level dict has no 'trainer:' entry — e.g. hand-written or trimmed old configs that only list hyperparameters.","commonSituations":"Migrating very old ML-Agents configs (pre-0.13 style) that predate explicit trainer_type; copying a partial example config; deleting the trainer line while cleaning up.","solutions":["Add a `trainer:` line to the config with the intended trainer type (ppo, sac, or poca).","If the config is a 3-component dict for a behavior, verify it is the full legacy dict including 'trainer', not a fragment.","Manually rewrite the config into the modern format (behaviors: <name>: with trainer_type, hyperparameters, network_settings) and skip the upgrade.","Check the original example configs shipped with your ML-Agents version and copy the trainer field from the matching trainer example."],"exampleFix":"// before (legacy config.yaml)\nbatch_size: 1024\nbeta: 0.01\nbuffer_size: 10240\n// after\ntrainer: ppo\nbatch_size: 1024\nbeta: 0.01\nbuffer_size: 10240","handlingStrategy":"validation","validationCode":"import yaml\n\ndef validate_legacy_config(path):\n    cfg = yaml.safe_load(open(path))\n    if not isinstance(cfg, dict) or \"trainer\" not in cfg:\n        raise ValueError(f\"{path} must define a top-level 'trainer: ppo|sac|poca' before conversion\")\n    return cfg","typeGuard":"def has_trainer_type(cfg: dict) -> bool:\n    return isinstance(cfg, dict) and isinstance(cfg.get(\"trainer\"), str) and cfg[\"trainer\"] in {\"ppo\", \"sac\", \"poca\"}","tryCatchPattern":"from mlagents.trainers.exception import TrainerConfigError\ntry:\n    convert_behavior_configs(args)\nexcept TrainerConfigError as e:\n    if \"specify a trainer type\" in str(e):\n        sys.exit(f\"Config error: add 'trainer:' to your YAML. {e}\")\n    raise","preventionTips":["Always include trainer: in legacy configs before running --convert-to-config.","Validate YAML against ML-Agents' TrainerSettings schema before conversion.","Start from the official example configs for the target trainer type.","Prefer manually migrating to the modern behaviors: format to avoid the upgrader."],"tags":["python","ml-agents","config","yaml","trainer-type"],"backgroundTag":"missing-config-key","analyzedSha":"3ecb446f75d1e7400eb404c562dc005d3164cffc","analyzedAt":"2026-09-02T16:33:12.832Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}