{"record":{"id":"c992fa7b6843e7ba","repo":"mlflow/mlflow","slug":"dictionary-key-type-must-be-str-got-args-0-in","errorCode":null,"errorMessage":"Dictionary key type must be str, got {args[0]} in type hint {_type_hint_repr(type_hint)}","messagePattern":"Dictionary key type must be str, got (.+?) in type hint (.+?)","errorType":"validation","errorClass":"InvalidTypeHintException","httpStatus":null,"severity":"error","filePath":"mlflow/types/type_hints.py","lineNumber":208,"sourceCode":"        )\n        return ColSpecType(dtype=AnyType(), required=True)\n    if datatype := TYPE_HINTS_TO_DATATYPE_MAPPING.get(type_hint):\n        return ColSpecType(dtype=datatype, required=True)\n    elif _is_pydantic_type_hint(type_hint):\n        dtype = _infer_type_from_pydantic_model(type_hint)\n        return ColSpecType(dtype=dtype, required=True)\n    elif origin_type := get_origin(type_hint):\n        args = get_args(type_hint)\n        if origin_type is list:\n            internal_type = _get_element_type_of_list_type_hint(type_hint)\n            return ColSpecType(\n                dtype=Array(_infer_colspec_type_from_type_hint(type_hint=internal_type).dtype),\n                required=True,\n            )\n        if origin_type is dict:\n            if len(args) == 2:\n                if args[0] != str:\n                    raise InvalidTypeHintException(\n                        message=f\"Dictionary key type must be str, got {args[0]} in type hint \"\n                        f\"{_type_hint_repr(type_hint)}\"\n                    )\n                return ColSpecType(\n                    dtype=Map(_infer_colspec_type_from_type_hint(type_hint=args[1]).dtype),\n                    required=True,\n                )\n            raise InvalidTypeHintException(\n                message=\"Dictionary type hint must contain two element types, got \"\n                f\"{_type_hint_repr(type_hint)}\"\n            )\n        if origin_type in UNION_TYPES:\n            if NONE_TYPE in args:\n                # This case shouldn't happen, but added for completeness\n                if len(args) < 2:\n                    raise InvalidTypeHintException(\n                        message=f\"Union type hint must contain at least one non-None type, \"\n                        f\"got {_type_hint_repr(type_hint)}\"","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/mlflow/mlflow/blob/6a27f2decc0b76eb1b54af31849784addb357dbc/mlflow/types/type_hints.py#L190-L226","documentation":"When inferring a ColSpec from a type hint in mlflow.types.type_hints, dict hints must have str as their key type because MLflow Map dtype only supports string keys. dict[int, X] or dict in Python 3.9+ Any other key type raises InvalidTypeHintException.","triggerScenarios":"Annotating a pydantic model field or predict signature parameter as Dict[int, float], Dict[Enum, str], Dict[bytes, X], or a non-str key type, then inferring a model signature (mlflow.models.infer_signature or set_signature).","commonSituations":"Models keyed by integer IDs or enum members; porting general Python typing to MLflow input schemas without realizing Map dtype requires string keys.","solutions":["Change the key type to str (Dict[str, X]) and convert keys (e.g. str(id)) before prediction","If keys must be non-string, restructure as a List of key/value dataclasses instead of a dict","For enum keys, use the enum's string name as the dict key"],"exampleFix":"// before\nclass Input(pydantic.BaseModel):\n    scores: Dict[int, float]\n// after\nclass Input(pydantic.BaseModel):\n    scores: Dict[str, float]  # Map dtype requires str keys\n# caller: {str(k): v for k, v in raw_scores.items()}","handlingStrategy":"type-guard","validationCode":"from typing import get_args, get_origin\nfor name, t in get_type_hints(MyModel).items():\n    if get_origin(t) is dict and get_args(t)[0] is not str:\n        raise TypeError(f\"{name}: dict keys must be str\")","typeGuard":"def is_str_keyged_map(t) -> bool:\n    from typing import get_origin, get_args\n    return get_origin(t) is dict and len(get_args(t)) == 2 and get_args(t)[0] is str","tryCatchPattern":"try:\n    infer_signature(train, model_input)\nexcept Exception as e:\n    if \"Dictionary key type must be str\" in str(e):\n        logging.error(\"Convert dict keys to str: %s\", e)\n    raise","preventionTips":["Use Dict[str, X] exclusively in signature type hints","Coerce non-string keys (e.g. str(id)) at prediction boundaries","Document the str-key requirement for shared signature models"],"tags":["python","typing","dict","colspec","type-hints"],"backgroundTag":"invalid-type-hint","analyzedSha":"6a27f2decc0b76eb1b54af31849784addb357dbc","analyzedAt":"2026-08-29T20:54:51.419Z","schemaVersion":2},"datasetVersion":"2026-08-29T22:17:34.462Z"}