{"record":{"id":"89fa3248553e4bc0","repo":"run-llama/llama_index","slug":"extractor-loading-requires-a-class-name","errorCode":null,"errorMessage":"Extractor loading requires a class_name","messagePattern":"Extractor loading requires a class_name","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"llama-index-core/llama_index/core/extractors/loading.py","lineNumber":18,"sourceCode":"from llama_index.core.extractors.metadata_extractors import (\n    BaseExtractor,\n    KeywordExtractor,\n    QuestionsAnsweredExtractor,\n    SummaryExtractor,\n    TitleExtractor,\n)\n\n\ndef load_extractor(\n    data: dict,\n) -> BaseExtractor:\n    if isinstance(data, BaseExtractor):\n        return data\n\n    extractor_name = data.get(\"class_name\")\n    if extractor_name is None:\n        raise ValueError(\"Extractor loading requires a class_name\")\n\n    if extractor_name == SummaryExtractor.class_name():\n        return SummaryExtractor.from_dict(data)\n    elif extractor_name == QuestionsAnsweredExtractor.class_name():\n        return QuestionsAnsweredExtractor.from_dict(data)\n    elif extractor_name == TitleExtractor.class_name():\n        return TitleExtractor.from_dict(data)\n    elif extractor_name == KeywordExtractor.class_name():\n        return KeywordExtractor.from_dict(data)\n    else:\n        raise ValueError(f\"Unknown extractor name: {extractor_name}\")\n","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/run-llama/llama_index/blob/afd0fef371831f9bda13e5af7167cf4e981278ab/llama-index-core/llama_index/core/extractors/loading.py#L1-L30","documentation":"Raised by load_extractor() when the input dict has no 'class_name' key. load_extractor reconstructs an extractor from its serialized dict form, and class_name is the discriminator used to pick the right from_dict constructor; it also short-circuits if the input is already a BaseExtractor instance.","triggerScenarios":"Calling load_extractor({'keywords': 3}) or load_extractor({}) on a hand-built or trimmed dict — e.g. one loaded from JSON that was serialized without the class discriminator, or a config section missing the type key.","commonSituations":"Persisting extractor configs with .model_dump(exclude=...) or json.dumps of a subset of fields; deserializing old config files; passing a list of kwargs dicts intended for direct constructor calls into load_extractor by mistake.","solutions":["Include the discriminator: data['class_name'] = 'KeywordExtractor' (or the appropriate extractor name) before calling load_extractor.","Serialize extractors with their full to_dict()/model_dump() output so class_name round-trips automatically.","If the dict is really just kwargs, construct the extractor class directly instead of using load_extractor."],"exampleFix":"# before\nextractor = load_extractor({\"keywords\": 3})\n\n# after\nextractor = load_extractor({\"class_name\": \"KeywordExtractor\", \"keywords\": 3})","handlingStrategy":"validation","validationCode":"if isinstance(data, dict) and \"class_name\" not in data:\n    raise ValueError(\"Extractor config dict must include 'class_name'\")\nextractor = load_extractor(data)","typeGuard":"def is_serialized_extractor(data: dict) -> bool:\n    return isinstance(data, dict) and isinstance(data.get(\"class_name\"), str)","tryCatchPattern":null,"preventionTips":["Persist extractors with full to_dict()/model_dump() output so class_name round-trips.","Schema-validate stored configs for the class_name discriminator.","Distinguish kwargs dicts (construct directly) from serialized dicts (load_extractor)."],"tags":["serialization","validation","configuration","missing-key"],"backgroundTag":null,"analyzedSha":"afd0fef371831f9bda13e5af7167cf4e981278ab","analyzedAt":"2026-08-15T05:42:58.429Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}