{"record":{"id":"b98df33708717c75","repo":"Unity-Technologies/ml-agents","slug":"a-non-terminal-lesson-does-not-have-a-completion-c","errorCode":null,"errorMessage":"A non-terminal lesson does not have a completion_criteria for {parameter_name}.","messagePattern":"A non-terminal lesson does not have a completion_criteria for (.+?)\\.","errorType":"validation","errorClass":"TrainerConfigError","httpStatus":null,"severity":"error","filePath":"ml-agents/mlagents/trainers/settings.py","lineNumber":548,"sourceCode":"@attr.s(auto_attribs=True)\nclass EnvironmentParameterSettings:\n    \"\"\"\n    EnvironmentParameterSettings is an ordered list of lessons for one environment\n    parameter.\n    \"\"\"\n\n    curriculum: List[Lesson]\n\n    @staticmethod\n    def _check_lesson_chain(lessons, parameter_name):\n        \"\"\"\n        Ensures that when using curriculum, all non-terminal lessons have a valid\n        CompletionCriteria, and that the terminal lesson does not contain a CompletionCriteria.\n        \"\"\"\n        num_lessons = len(lessons)\n        for index, lesson in enumerate(lessons):\n            if index < num_lessons - 1 and lesson.completion_criteria is None:\n                raise TrainerConfigError(\n                    f\"A non-terminal lesson does not have a completion_criteria for {parameter_name}.\"\n                )\n            if index == num_lessons - 1 and lesson.completion_criteria is not None:\n                warnings.warn(\n                    f\"Your final lesson definition contains completion_criteria for {parameter_name}.\"\n                    f\"It will be ignored.\",\n                    TrainerConfigWarning,\n                )\n\n    @staticmethod\n    def structure(d: Mapping, t: type) -> Dict[str, \"EnvironmentParameterSettings\"]:\n        \"\"\"\n        Helper method to structure a Dict of EnvironmentParameterSettings class. Meant\n        to be registered with cattr.register_structure_hook() and called with\n        cattr.structure().\n        \"\"\"\n        if not isinstance(d, Mapping):\n            raise TrainerConfigError(","sourceCodeStart":530,"sourceCodeEnd":566,"githubUrl":"https://github.com/Unity-Technologies/ml-agents/blob/3ecb446f75d1e7400eb404c562dc005d3164cffc/ml-agents/mlagents/trainers/settings.py#L530-L566","documentation":"In a curriculum, every lesson except the last must define a CompletionCriteria so the trainer knows when to advance; only the terminal lesson must omit it. mlagents raises TrainerConfigError when a non-final lesson lacks completion_criteria.","triggerScenarios":"A curriculum parameter has multiple lessons but an intermediate (non-terminal) lesson has no completion_criteria block, e.g. a lesson inserted or criteria deleted when editing the config.","commonSituations":"Adding a new lesson to the middle of a curriculum and forgetting its criteria; simplifying configs by removing a criteria block; copying a terminal lesson as a template for a mid-curriculum lesson.","solutions":["Add a completion_criteria (with measure and threshold) to every non-final lesson in that parameter's lessons list.","Remove completion_criteria from the final lesson only (it is terminal and any criteria there are ignored with a warning).","Re-order lessons so the lesson without criteria is last."],"exampleFix":"// before\nlessons:\n  - value: 0.0\n  - value: 5.0\n    completion_criteria:\n      measure: progress\n      threshold: 0.5\n// after\nlessons:\n  - value: 0.0\n    completion_criteria:\n      measure: progress\n      threshold: 0.5\n  - value: 5.0","handlingStrategy":"validation","validationCode":"def validate_curriculum(param_cfg):\n    lessons = param_cfg['curriculum']['lessons']\n    for i, lesson in enumerate(lessons[:-1]):\n        assert 'completion_criteria' in lesson, f'lesson {i} missing completion_criteria'\n    assert 'completion_criteria' not in lessons[-1], 'final lesson must not have completion_criteria'","typeGuard":"def is_terminal_lesson(index, lessons):\n    return index == len(lessons) - 1","tryCatchPattern":"try:\n    config = load_config(path)\nexcept TrainerConfigError as e:\n    if 'completion_criteria' in str(e):\n        logger.error('Curriculum chain broken: %s', e)","preventionTips":["Every lesson except the last must have completion_criteria","Never put completion_criteria on the final lesson","Run config validation as part of CI before launching training"],"tags":["config","curriculum","ml-agents"],"backgroundTag":"missing-required-config-field","analyzedSha":"3ecb446f75d1e7400eb404c562dc005d3164cffc","analyzedAt":"2026-09-02T16:33:12.832Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}