{"record":{"id":"b8d3b08750e8ecd2","repo":"huggingface/transformers","slug":"early-stopping-must-be-a-boolean-or-never-but","errorCode":null,"errorMessage":"`early_stopping` must be a boolean or 'never', but is {}.","messagePattern":"`early_stopping` must be a boolean or 'never', but is (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/transformers/generation/configuration_utils.py","lineNumber":668,"sourceCode":"        of parameterization that can be detected as incorrect from the configuration instance alone.\n\n        Note that some parameters not validated here are best validated at generate runtime, as they may depend on\n        other inputs and/or the model, such as parameters related to the generation length.\n\n        Args:\n            strict (bool): If True, raise an exception for any issues found. If False, only log issues.\n            user_set_attributes (set[str], *optional*): Names of attributes the caller explicitly provided. When\n                supplied, \"minor issue\" warnings about conflicting flag combinations (e.g. sampling-only flags set\n                while `do_sample=False`) only fire if the conflicting flag is in this set -- avoiding noisy warnings\n                when the value was inherited from a model's default `generation_config.json`. When `None`, all set\n                attributes are considered user-set (backward-compatible behavior for direct `validate()` calls).\n        \"\"\"\n        minor_issues = {}  # format: {attribute_name: issue_description}\n\n        # 1. Validation of individual attributes\n        # 1.1. Decoding attributes\n        if self.early_stopping not in {None, True, False, \"never\"}:\n            raise ValueError(f\"`early_stopping` must be a boolean or 'never', but is {self.early_stopping}.\")\n        if self.max_new_tokens is not None and self.max_new_tokens <= 0:\n            raise ValueError(f\"`max_new_tokens` must be greater than 0, but is {self.max_new_tokens}.\")\n        if self.assistant_ensemble_weight is not None and not (0.0 < self.assistant_ensemble_weight < 1.0):\n            raise ValueError(\n                f\"`assistant_ensemble_weight` must be in the open interval `(0.0, 1.0)`, \"\n                f\"but is {self.assistant_ensemble_weight}. Use `None` for standard (lossless) speculative decoding.\"\n            )\n        if self.pad_token_id is not None and self.pad_token_id < 0:\n            minor_issues[\"pad_token_id\"] = (\n                f\"`pad_token_id` should be positive but got {self.pad_token_id}. This will cause errors when batch \"\n                \"generating, if there is padding. Please set `pad_token_id` explicitly as \"\n                \"`model.generation_config.pad_token_id=PAD_TOKEN_ID` to avoid errors in generation\"\n            )\n        # 1.2. Cache attributes\n        # \"paged\" re-routes to continuous batching and so it is a valid cache implementation. But we do not want to test\n        # it with the `generate` as the other would be, so we we cannot add it to ALL_CACHE_IMPLEMENTATIONS\n        valid_cache_implementations = ALL_CACHE_IMPLEMENTATIONS + (\"paged\",)\n        if self.cache_implementation is not None and self.cache_implementation not in valid_cache_implementations:","sourceCodeStart":650,"sourceCodeEnd":686,"githubUrl":"https://github.com/huggingface/transformers/blob/a597f974857b3d92939971296bc0deb93d33d780/src/transformers/generation/configuration_utils.py#L650-L686","documentation":"GenerationConfig.validate() enforces that early_stopping is one of None, True, False, or the string 'never' (the 'never' mode never stops early even if all beams are finished). Any other value — e.g. the string 'true', 1, or 'always' — is rejected because beam-search logic cannot interpret it.","triggerScenarios":"GenerationConfig(early_stopping='yes'), model.generation_config.early_stopping = 1, or a generation_config.json containing a non-boolean early_stopping; validate() runs at generation start.","commonSituations":"Hand-edited generation_config.json where booleans became strings; configs round-tripped through YAML/JSON tooling that coerces types; copy-pasting from docs that show 'never' and assuming other strings work.","solutions":["Set early_stopping to True, False, None, or exactly 'never'","Fix generation_config.json files where true/false were quoted as strings","If loading configs from external sources, normalize known boolean fields before validate()"],"exampleFix":"# before\ncfg = GenerationConfig(early_stopping=\"true\")\n# after\ncfg = GenerationConfig(early_stopping=True)","handlingStrategy":"validation","validationCode":"def valid_early_stopping(v) -> bool:\n    return v in (None, True, False, \"never\")","typeGuard":"from typing import Union\n\ndef is_valid_early_stopping(v) -> bool:\n    return v is None or isinstance(v, bool) or v == \"never\"","tryCatchPattern":null,"preventionTips":["Normalize booleans in generation_config.json (unquoted true/false)","Run GenerationConfig.validate() right after construction to fail before long setups"],"tags":["python","transformers","generation","generation-config","validation"],"backgroundTag":null,"analyzedSha":"a597f974857b3d92939971296bc0deb93d33d780","analyzedAt":"2026-08-14T18:24:08.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}