{"record":{"id":"a7893dae9b089607","repo":"vllm-project/vllm","slug":"expected-str-or-quantkey-got-type-v-name","errorCode":null,"errorMessage":"expected str or QuantKey, got {type(v).__name__}","messagePattern":"expected str or QuantKey, got (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"vllm/config/quantization.py","lineNumber":43,"sourceCode":"# User-facing names addressable from quantization_config.\nQUANT_KEY_NAMES: dict[str, QuantKey] = {\n    \"fp8_per_tensor_static\": kFp8StaticTensorSym,\n    \"fp8_per_tensor_dynamic\": kFp8DynamicTensorSym,\n    \"fp8_per_token\": kFp8DynamicTokenSym,\n    \"fp8_per_channel_static\": kFp8StaticChannelSym,\n    \"fp8_per_block_static\": kFp8Static128BlockSym,\n    \"fp8_per_block_dynamic\": kFp8Dynamic128Sym,\n    \"mxfp8\": kMxfp8Dynamic,\n    \"mxfp4\": kMxfp4Dynamic,\n    \"int8_per_channel_static\": kInt8StaticChannelSym,\n}\n\n\ndef _coerce_quant_key(v: Any) -> QuantKey | None:\n    if v is None or isinstance(v, QuantKey):\n        return v\n    if not isinstance(v, str):\n        raise TypeError(f\"expected str or QuantKey, got {type(v).__name__}\")\n    try:\n        return QUANT_KEY_NAMES[v]\n    except KeyError:\n        raise ValueError(\n            f\"unknown quantization name {v!r}; \"\n            f\"expected one of {sorted(QUANT_KEY_NAMES)}\"\n        ) from None\n\n\n# Stop pydantic from introspecting QuantKey: it transitively contains a\n# NamedTuple with `ClassVar[GroupShape]` declarations that pydantic refuses.\nQuantKeyField = Annotated[\n    QuantKey | None,\n    GetPydanticSchema(\n        lambda _src, _handler: core_schema.no_info_plain_validator_function(\n            _coerce_quant_key\n        )\n    ),","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/vllm-project/vllm/blob/c794754062d49a8fdb63ab3c5215b488b865030c/vllm/config/quantization.py#L25-L61","documentation":"_coerce_quant_key is the pydantic BeforeValidator that coerces quantization names into QuantKey objects. It raises TypeError when the input value is neither None, a QuantKey instance, nor a str — e.g. an int, list, or dict was supplied where a quantization method name string is expected.","triggerScenarios":"Passing a non-string value into a quantization config field that routes through _coerce_quant_key — e.g. quantization=8, quantization=['fp8'], or quantization={'method': 'fp8'} — instead of quantization='fp8' (or a QuantKey instance / None).","commonSituations":"Programmatically building quantization configs from untyped data (JSON numbers, parsed CLI ints like --quantization 8); passing an enum or object from another library where a name string is required.","solutions":["Pass the quantization method as a string name, e.g. 'fp8', 'awq', 'gptq'.","Or pass None to leave quantization auto-detected, or a QuantKey instance.","Sanitize external input: str(...) coerce or validate isinstance(v, str) before building the config."],"exampleFix":"# before\nquant_cfg = QuantizationConfig(quantization=8)  # TypeError\n\n# after\nquant_cfg = QuantizationConfig(quantization='fp8')","handlingStrategy":"type-guard","validationCode":"def coerce_quant_name(v):\n    if v is None or isinstance(v, (str, QuantKey)):\n        return v\n    if isinstance(v, (int, float)):\n        return str(v)  # or reject explicitly\n    raise TypeError(f\"quantization name must be str, got {type(v).__name__}\")","typeGuard":"from vllm.config.quantization import QuantKey\n\ndef is_quant_name(v) -> TypeGuard[str | QuantKey | None]:\n    return v is None or isinstance(v, (str, QuantKey))","tryCatchPattern":"try:\n    cfg = ModelConfig(..., quantization=quant)\nexcept TypeError as e:\n    if \"expected str or QuantKey\" in str(e):\n        cfg = ModelConfig(..., quantization=str(quant))\n    else:\n        raise","preventionTips":["Validate quantization values against isinstance(v, str) when configs come from JSON/CLI input.","Reference valid names via vllm.config.quantization.QUANT_KEY_NAMES instead of free-typing strings."],"tags":["quantization","type-validation","pydantic","api-misuse"],"backgroundTag":null,"analyzedSha":"c794754062d49a8fdb63ab3c5215b488b865030c","analyzedAt":"2026-08-14T21:17:39.825Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}