{"record":{"id":"d277bcfcbd3efdd9","repo":"mlflow/mlflow","slug":"max-length-must-be-non-negative-got-self-max","errorCode":null,"errorMessage":"`max_length` must be non-negative, got ${self.max_length}.","messagePattern":"`max_length` must be non-negative, got (.+?)\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mlflow/genai/scorers/builtin_scorers.py","lineNumber":3527,"sourceCode":"    \"\"\"\n\n    name: str = \"response_length\"\n    min_length: int | None = None\n    max_length: int | None = None\n    unit: Literal[\"chars\", \"words\"] = \"chars\"\n    required_columns: set[str] = {\"outputs\"}\n    description: str = \"Check whether the output length is within specified bounds.\"\n\n    @pydantic.model_validator(mode=\"after\")\n    def _validate_bounds(self):\n        if self.min_length is None and self.max_length is None:\n            raise ValueError(\n                \"ResponseLength requires at least one of `min_length` or `max_length`.\"\n            )\n        if self.min_length is not None and self.min_length < 0:\n            raise ValueError(f\"`min_length` must be non-negative, got {self.min_length}.\")\n        if self.max_length is not None and self.max_length < 0:\n            raise ValueError(f\"`max_length` must be non-negative, got {self.max_length}.\")\n        if (\n            self.min_length is not None\n            and self.max_length is not None\n            and self.min_length > self.max_length\n        ):\n            raise ValueError(\n                f\"`min_length` ({self.min_length}) must be <= `max_length` ({self.max_length}).\"\n            )\n        return self\n\n    @property\n    def feedback_value_type(self) -> Any:\n        return Literal[\"yes\", \"no\"]\n\n    @property\n    def instructions(self) -> str:\n        bounds = []\n        if self.min_length is not None:","sourceCodeStart":3509,"sourceCodeEnd":3545,"githubUrl":"https://github.com/mlflow/mlflow/blob/6a27f2decc0b76eb1b54af31849784addb357dbc/mlflow/genai/scorers/builtin_scorers.py#L3509-L3545","documentation":"The ResponseLength built-in scorer validates its bounds in a pydantic model_validator at construction time. It throws when `max_length` is provided but is a negative number, because a maximum length cannot be below zero. This is fail-fast input validation so users learn about bad config before any evaluation runs.","triggerScenarios":"Constructing ResponseLength(max_length=<negative int>) directly or via mlflow.genai.evaluate(scorers=[ResponseLength(...)]), e.g. ResponseLength(max_length=-1) or a computed bound that evaluated negative.","commonSituations":"Computing the bound from a variable/config that defaults to -1 or 0-1 on an empty collection (e.g. max(len(x) for x in []) guarded with -1); sign-flipped min/max variables; YAML/env config parsed into negative numbers.","solutions":["Inspect the value passed as max_length and ensure it is >= 0","If only an upper bound is unwanted, pass max_length=None and rely on min_length alone","Trace where the bound is computed from and fix the source expression/config value"],"exampleFix":"// before\nResponseLength(max_length=-1)\n// after\nResponseLength(max_length=500)  # or ResponseLength(min_length=10)","handlingStrategy":"validation","validationCode":"def safe_max_length(v):\n    if v is not None and v < 0:\n        raise ValueError(f\"max_length must be >= 0, got {v}\")\n    return v\nResponseLength(max_length=safe_max_length(max_len))","typeGuard":"def is_valid_max_length(v) -> bool:\n    return v is None or (isinstance(v, int) and v >= 0)","tryCatchPattern":null,"preventionTips":["Clamp computed bounds: max_length = max(0, computed)","Never default bounds to -1; use None for 'unset'","Add unit tests constructing every scorer with your config values"],"tags":["validation","python","pydantic","genai-scorers"],"backgroundTag":"invalid-parameter-value","analyzedSha":"6a27f2decc0b76eb1b54af31849784addb357dbc","analyzedAt":"2026-08-29T20:54:51.419Z","schemaVersion":2},"datasetVersion":"2026-08-29T22:17:34.462Z"}