Unity-Technologies/ml-agents · error · TrainerConfigError

Unsupported config {d} for {t.__name__}.

Error message

Unsupported config {d} for {t.__name__}.

What it means

TrainerConfigError raised by strict_to_cls when the value being structured into a settings class is not a Mapping (dict). The YAML deserializer expects every config section (trainer settings, hyperparameters, reward signals) to be a dict of keys; if a scalar, string, or list is supplied where a mapping is required, conversion to the attrs class fails.

Source

Thrown at ml-agents/mlagents/trainers/settings.py:63

    return cattr.structure(value, attr_fields_dict[key].type)


def check_hyperparam_schedules(val: Dict, trainer_type: str) -> Dict:
    # Check if beta and epsilon are set. If not, set to match learning rate schedule.
    if trainer_type == "ppo" or trainer_type == "poca":
        if "beta_schedule" not in val.keys() and "learning_rate_schedule" in val.keys():
            val["beta_schedule"] = val["learning_rate_schedule"]
        if (
            "epsilon_schedule" not in val.keys()
            and "learning_rate_schedule" in val.keys()
        ):
            val["epsilon_schedule"] = val["learning_rate_schedule"]
    return val


def strict_to_cls(d: Mapping, t: type) -> Any:
    if not isinstance(d, Mapping):
        raise TrainerConfigError(f"Unsupported config {d} for {t.__name__}.")
    d_copy: Dict[str, Any] = {}
    d_copy.update(d)
    for key, val in d_copy.items():
        d_copy[key] = check_and_structure(key, val, t)
    return t(**d_copy)


def defaultdict_to_dict(d: DefaultDict) -> Dict:
    return {key: cattr.unstructure(val) for key, val in d.items()}


def deep_update_dict(d: Dict, update_d: Mapping) -> None:
    """
    Similar to dict.update(), but works for nested dicts of dicts as well.
    """
    for key, val in update_d.items():
        if key in d and isinstance(d[key], Mapping) and isinstance(val, Mapping):
            deep_update_dict(d[key], val)

View on GitHub (pinned to 3ecb446f75)

Solutions

  1. Ensure the flagged section is a YAML mapping: use key: value pairs under the section header, not a bare scalar or list.
  2. Fix indentation so nested sections (hyperparameters, network_settings, reward_signals) contain sub-keys as dicts.
  3. Write reward signal entries as mappings: extrinsic:\n strength: 1.0, not extrinsic: 1.0.
  4. Validate the YAML parses as expected with a quick python -c "import yaml; print(yaml.safe_load(open('config.yaml')))".

Example fix

# before
reward_signals:
  extrinsic: 1.0
# after
reward_signals:
  extrinsic:
    gamma: 0.99
    strength: 1.0
Defensive patterns

Strategy: validation

Validate before calling

import yaml
raw = yaml.safe_load(open("config.yaml"))
for section in ("hyperparameters", "network_settings", "reward_signals"):
    val = raw.get(section)
    if val is not None and not isinstance(val, dict):
        raise ValueError(f"Section '{section}' must be a YAML mapping, got {type(val).__name__}")

Type guard

from typing import Mapping
def is_mapping_config(v) -> bool:
    return isinstance(v, Mapping)

Try / catch

from mlagents.trainers.exception import TrainerConfigError
try:
    settings = load_config("config.yaml")
except TrainerConfigError as e:
    logger.error(f"Config section is not a mapping: {e}")
    raise SystemExit(1)

Prevention

When it happens

Trigger: A YAML section given a non-dict value, e.g. hyperparameters: 123, reward_signals: extrinsic, or a reward signal entry like extrinsic: 1.0 instead of extrinsic: {strength: 1.0}; also mis-indented YAML that collapses a section into a string.

Common situations: YAML indentation errors that turn a nested block into a scalar; hand-written configs where reward signals or network_settings were written as bare scalars; programmatic config building passing a list instead of a dict.

Related errors


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