{"record":{"id":"d834c74103364af4","repo":"kovidgoyal/kitty","slug":"invalid-number-with-unit-x","errorCode":null,"errorMessage":"Invalid number with unit: {x}","messagePattern":"Invalid number with unit: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"kitty/conf/utils.py","lineNumber":83,"sourceCode":"def unit_float(x: ConvertibleToNumbers) -> float:\n    return max(0, min(float(x), 1))\n\n\ndef signed_unit_float(x: ConvertibleToNumbers) -> float:\n    return max(-1, min(float(x), 1))\n\n\ndef number_with_unit(x: str, default_unit: str, *extra_units: str) -> tuple[float, str]:\n    if (mat := number_unit_pat.match(x)) is not None:\n        try:\n            value = float(mat.group(1))\n        except Exception as e:\n            raise ValueError(f'Not a number: {x} with error: {e}')\n        unit = mat.group(2) or default_unit\n        if unit != default_unit and unit not in extra_units:\n            raise ValueError(f'Not a valid unit: {x}. Allowed units are: {default_unit}, {\", \".join(extra_units)}')\n        return value, unit\n    raise ValueError(f'Invalid number with unit: {x}')\n\n\ndef to_bool(x: str) -> bool:\n    return x.lower() in ('y', 'yes', 'true')\n\n\nclass ToCmdline:\n    def __init__(self) -> None:\n        self.override_env: dict[str, str] | None = None\n\n    def __enter__(self) -> 'ToCmdline':\n        return self\n\n    def __exit__(self, *a: Any) -> None:\n        self.override_env = None\n\n    def filter_env_vars(self, *a: str, **override: str) -> 'ToCmdline':\n        remove = frozenset(a)","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/kovidgoyal/kitty/blob/6d5d0c440603ad9bdf6dcd599f73f6dde21acb44/kitty/conf/utils.py#L65-L101","documentation":"number_with_unit raises ValueError('Invalid number with unit: {x}') when the whole string does not match the number+unit pattern at all — the value isn't recognizable as a number with an optional unit.","triggerScenarios":"Config values like 'big', '10 20', '-', or empty strings passed to an option parsed by number_with_unit.","commonSituations":"Typos, missing values, or shell expansion gone wrong in kitty.conf or programmatically generated config.","solutions":["Supply a plain number or number+allowed unit","Quote the config line if generated from shell variables","Validate the value before writing the config"],"exampleFix":"# before\ntext_fg_override_threshold\n# after\ntext_fg_override_threshold 20","handlingStrategy":"validation","validationCode":"import re\nis_number_with_unit = re.fullmatch(r'[+-]?(\\d+\\.?\\d*|\\.\\d+)\\w*', x) is not None","typeGuard":null,"tryCatchPattern":"try:\n    v, u = number_with_unit(x, 'px')\nexcept ValueError:\n    v, u = 0.0, 'px'","preventionTips":["Never leave numeric options blank in generated configs","Lint kitty.conf values with a regex before deploying"],"tags":["kitty","config","number-parsing","valueerror"],"backgroundTag":"invalid-config-value","analyzedSha":"6d5d0c440603ad9bdf6dcd599f73f6dde21acb44","analyzedAt":"2026-08-27T14:20:20.142Z","schemaVersion":2},"datasetVersion":"2026-08-27T19:17:21.184Z"}