{"record":{"id":"6c72c4c17112d9ce","repo":"huggingface/transformers","slug":"stoppingcriteria-needs-to-be-subclassed","errorCode":null,"errorMessage":"StoppingCriteria needs to be subclassed","messagePattern":"StoppingCriteria needs to be subclassed","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"src/transformers/generation/stopping_criteria.py","lineNumber":55,"sourceCode":"\n    Return:\n        `torch.BoolTensor`. (`torch.BoolTensor` of shape `(batch_size, 1)`):\n            `True` indicates we stop generation for a particular row.\n            `False` indicates we should continue.\n\n\"\"\"\n\n\nclass StoppingCriteria(ABC):\n    \"\"\"Abstract base class for all stopping criteria that can be applied during generation.\n\n    If your stopping criteria depends on the `scores` input, make sure you pass `return_dict_in_generate=True,\n    output_scores=True` to `generate`.\n    \"\"\"\n\n    @add_start_docstrings(STOPPING_CRITERIA_INPUTS_DOCSTRING)\n    def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor, **kwargs) -> torch.BoolTensor:\n        raise NotImplementedError(\"StoppingCriteria needs to be subclassed\")\n\n\nclass MaxLengthCriteria(StoppingCriteria):\n    \"\"\"\n    This class can be used to stop generation whenever the full generated number of tokens exceeds `max_length`. Keep\n    in mind for decoder-only type of transformers, this will include the initial prompted tokens.\n\n    Args:\n        max_length (`int`):\n            The maximum length that the output sequence can have in number of tokens.\n        max_position_embeddings (`int`, *optional*):\n            The maximum model length, as defined by the model's `config.max_position_embeddings` attribute.\n    \"\"\"\n\n    def __init__(self, max_length: int, max_position_embeddings: int | None = None):\n        self.max_length = max_length\n        self.max_position_embeddings = max_position_embeddings\n","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/huggingface/transformers/blob/a597f974857b3d92939971296bc0deb93d33d780/src/transformers/generation/stopping_criteria.py#L37-L73","documentation":"NotImplementedError raised by the abstract StoppingCriteria.__call__ in transformers/generation/stopping_criteria.py. StoppingCriteria is an ABC-style base class; its __call__ intentionally raises so that any criteria object used in generate(stopping_criteria=...) must override __call__. You get this when the base class (or a subclass that forgot to override __call__) is actually invoked.","triggerScenarios":"Instantiating StoppingCriteria() directly and passing it to generate(); subclassing StoppingCriteria but naming the method something else (e.g. __call__(self, input_ids, scores) misspelled, or defining call() instead of __call__); subclassing a criteria like MaxLengthCriteria but overriding __init__ only.","commonSituations":"Writing a custom stop-on-keyword criteria and forgetting the exact __call__(self, input_ids, scores, **kwargs) signature; renaming during refactor so Python resolves to the base __call__.","solutions":["Subclass StoppingCriteria and implement __call__(self, input_ids, scores, **kwargs) -> torch.BoolTensor returning a per-batch bool tensor.","Alternatively subclass an existing concrete criteria (e.g. StopStringCriteria, MaxLengthCriteria) and override its logic.","Never pass the bare StoppingCriteria instance into generate()."],"exampleFix":"# before\nclass MyStop(StoppingCriteria):\n    def check(self, input_ids, scores, **kwargs):  # wrong name\n        return input_ids.shape[1] > 50\n\n# after\nclass MyStop(StoppingCriteria):\n    def __call__(self, input_ids, scores, **kwargs):\n        return input_ids.shape[1] > 50 * torch.ones(input_ids.shape[0], dtype=torch.bool, device=input_ids.device)","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"def is_usable_stopping_criteria(c) -> bool:\n    return (\n        not type(c).__name__ == \"StoppingCriteria\"\n        and callable(getattr(c, \"__call__\", None))\n        and type(c).__call__ is not StoppingCriteria.__call__\n    )","tryCatchPattern":null,"preventionTips":["Always implement __call__(self, input_ids, scores, **kwargs) -> BoolTensor in subclasses; match the signature exactly.","Add a unit test that calls your criteria once with dummy tensors before wiring it into generate.","Consider subclassing an existing concrete criteria and overriding its logic."],"tags":["stopping-criteria","abstract-class","generation","subclassing"],"backgroundTag":null,"analyzedSha":"a597f974857b3d92939971296bc0deb93d33d780","analyzedAt":"2026-08-14T18:24:08.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}