{"record":{"id":"3a562e1c3f9bfab7","repo":"Unity-Technologies/ml-agents","slug":"threshold-for-next-lesson-cannot-be-negative-when","errorCode":null,"errorMessage":"Threshold for next lesson cannot be negative when the measure is progress.","messagePattern":"Threshold for next lesson cannot be negative when the measure is progress\\.","errorType":"validation","errorClass":"TrainerConfigError","httpStatus":null,"severity":"error","filePath":"ml-agents/mlagents/trainers/settings.py","lineNumber":485,"sourceCode":"    measure: MeasureType = attr.ib(default=MeasureType.REWARD)\n    min_lesson_length: int = 0\n    signal_smoothing: bool = True\n    threshold: float = attr.ib(default=0.0)\n    require_reset: bool = False\n\n    @threshold.validator\n    def _check_threshold_value(self, attribute, value):\n        \"\"\"\n        Verify that the threshold has a value between 0 and 1 when the measure is\n        PROGRESS\n        \"\"\"\n        if self.measure == self.MeasureType.PROGRESS:\n            if self.threshold > 1.0:\n                raise TrainerConfigError(\n                    \"Threshold for next lesson cannot be greater than 1 when the measure is progress.\"\n                )\n            if self.threshold < 0.0:\n                raise TrainerConfigError(\n                    \"Threshold for next lesson cannot be negative when the measure is progress.\"\n                )\n\n    def need_increment(\n        self, progress: float, reward_buffer: List[float], smoothing: float\n    ) -> Tuple[bool, float]:\n        \"\"\"\n        Given measures, this method returns a boolean indicating if the lesson\n        needs to change now, and a float corresponding to the new smoothed value.\n        \"\"\"\n        # Is the min number of episodes reached\n        if len(reward_buffer) < self.min_lesson_length:\n            return False, smoothing\n        if self.measure == CompletionCriteriaSettings.MeasureType.PROGRESS:\n            if progress > self.threshold:\n                return True, smoothing\n        if self.measure == CompletionCriteriaSettings.MeasureType.REWARD:\n            if len(reward_buffer) < 1:","sourceCodeStart":467,"sourceCodeEnd":503,"githubUrl":"https://github.com/Unity-Technologies/ml-agents/blob/3ecb446f75d1e7400eb404c562dc005d3164cffc/ml-agents/mlagents/trainers/settings.py#L467-L503","documentation":"When a curriculum lesson uses MeasureType.PROGRESS, the completion threshold represents a fraction of lessons completed and must lie in [0.0, 1.0]. mlagents throws TrainerConfigError during config validation because a negative threshold is meaningless for progress-based advancement.","triggerScenarios":"A YAML/JSON curriculum defines a lesson with completion_criteria: threshold less than 0.0 while measure: progress (e.g. threshold: -0.5, a typo or copy-paste from a reward/progress-based config).","commonSituations":"Hand-editing curriculum configs, converting configs between measure types (reward thresholds can be negative, progress cannot), or templated config generation producing bad values.","solutions":["Set the threshold to a value between 0.0 and 1.0 (e.g. 0.5 for advancing after 50% of episodes complete).","If you intended reward-strength-based advancement, change measure to reward and use an appropriate reward threshold.","Check for stray minus signs from templating or string concatenation when generating configs."],"exampleFix":"// before\nmeasure: progress\ncompletion_criteria:\n  threshold: -0.2\n// after\nmeasure: progress\ncompletion_criteria:\n  threshold: 0.3","handlingStrategy":"validation","validationCode":"def validate_progress_threshold(measure, threshold):\n    if measure == 'progress' and not (0.0 <= threshold <= 1.0):\n        raise ValueError('progress threshold must be in [0.0, 1.0], got %r' % threshold)","typeGuard":"def is_valid_threshold(x):\n    return isinstance(x, (int, float)) and 0.0 <= x <= 1.0","tryCatchPattern":"from mlagents.trainers.exception import TrainerConfigError\ntry:\n    load_config(path)\nexcept TrainerConfigError as e:\n    logger.error('Invalid curriculum threshold: %s', e)","preventionTips":["Keep progress thresholds within 0-1; reserve negative thresholds for reward measures","Validate curriculum blocks with a linter or unit test before training","Avoid templating that inserts values without range checks"],"tags":["config","curriculum","ml-agents"],"backgroundTag":"invalid-config-threshold","analyzedSha":"3ecb446f75d1e7400eb404c562dc005d3164cffc","analyzedAt":"2026-09-02T16:33:12.832Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}