{"record":{"id":"22ea80d3ba083224","repo":"mudler/LocalAI","slug":"attention-backend-must-be-one-of-choices","errorCode":null,"errorMessage":"attention_backend must be one of: {choices}","messagePattern":"attention_backend must be one of: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"backend/python/longcat-video/longcat_utils.py","lineNumber":122,"sourceCode":"\ndef require_float(value, name, minimum=None, maximum=None):\n    try:\n        parsed = float(value)\n    except (TypeError, ValueError) as err:\n        raise ValueError(f\"{name} must be a number\") from err\n    if minimum is not None and parsed < minimum:\n        raise ValueError(f\"{name} must be at least {minimum}\")\n    if maximum is not None and parsed > maximum:\n        raise ValueError(f\"{name} must be at most {maximum}\")\n    return parsed\n\n\ndef attention_overrides(name):\n    try:\n        return dict(ATTENTION_OVERRIDES[name])\n    except KeyError as err:\n        choices = \", \".join(ATTENTION_OVERRIDES)\n        raise ValueError(f\"attention_backend must be one of: {choices}\") from err\n\n\ndef _model_name_from_directory(path):\n    for filename in (\"model_index.json\", \"config.json\"):\n        config_path = os.path.join(path, filename)\n        try:\n            with open(config_path, \"r\", encoding=\"utf-8\") as config_file:\n                model_name = json.load(config_file).get(\"model_name\", \"\")\n        except (FileNotFoundError, OSError, ValueError, TypeError):\n            continue\n        if model_name:\n            return model_name\n    return \"\"\n\n\ndef normalize_model_source(model):\n    value = model.rstrip(\"/\")\n    for prefix in (\"huggingface://\", \"hf://\"):","sourceCodeStart":104,"sourceCodeEnd":140,"githubUrl":"https://github.com/mudler/LocalAI/blob/44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26/backend/python/longcat-video/longcat_utils.py#L104-L140","documentation":"Raised by attention_overrides() in longcat-video when the requested attention_backend key is absent from the ATTENTION_OVERRIDES dict. The error message enumerates the valid choices so the user can correct the name. The original KeyError is chained.","triggerScenarios":"Calling attention_overrides(name) with a backend string that is not a key in ATTENTION_OVERRIDES — typo like 'sdpa ' (trailing space), 'flash-attn' vs 'flash_attn' underscore/hyphen mismatch, or a backend name from a newer/older version.","commonSituations":"Copy-pasted config from another project using different naming (flashattn vs flash_attn2), version drift where a backend key was renamed, or case sensitivity ('SDPA' vs 'sdpa').","solutions":["Use one of the choices listed in the error message verbatim","Strip/normalize whitespace and check underscore vs hyphen spelling","Check the ATTENTION_OVERRIDES dict in longcat_utils.py for the exact keys this version supports"],"exampleFix":"# before\nattention_overrides('flash-attn2')  # ValueError: must be one of: ...\n\n# after\nattention_overrides('flash_attn2')  # exact key from ATTENTION_OVERRIDES","handlingStrategy":"type-guard","validationCode":"from longcat_utils import ATTENTION_OVERRIDES\nbackend = (request.attention_backend or '').strip()\nif backend not in ATTENTION_OVERRIDES:\n    raise ValueError(f'unsupported attention_backend {backend!r}; choose from {sorted(ATTENTION_OVERRIDES)}')\noverrides = attention_overrides(backend)","typeGuard":"def is_valid_attention_backend(name: str) -> bool:\n    return name in ATTENTION_OVERRIDES","tryCatchPattern":"try:\n    ov = attention_overrides(name)\nexcept ValueError as err:\n    # message already lists valid choices; surface it to the user\n    return error_response(str(err))","preventionTips":["Derive dropdown options from ATTENTION_OVERRIDES keys","Strip whitespace and normalize hyphens/underscores before lookup","Pin the backend version so the key set cannot drift"],"tags":["python","validation","enum","longcat-video","attention"],"backgroundTag":null,"analyzedSha":"44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26","analyzedAt":"2026-08-15T10:13:50.291Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}