{"record":{"id":"4be49bc6d6e2849b","repo":"deepset-ai/haystack","slug":"could-not-import-fully-qualified-name","errorCode":null,"errorMessage":"Could not import '{fully_qualified_name}'","messagePattern":"Could not import '(.+?)'","errorType":"exception","errorClass":"ImportError","httpStatus":null,"severity":"error","filePath":"haystack/utils/type_serialization.py","lineNumber":346,"sourceCode":"        module = thread_safe_import(module_path)\n        resolved = getattr(module, attr_name)\n        # `_check_module_allowed` above gates the declared module path, which the caller controls.\n        # A class/module re-exported as an attribute of an allowlisted module (e.g.\n        # `haystack.utils.auth.os` -> the `os` module, or a re-exported `subprocess.Popen`) would\n        # otherwise slip through. Re-check the module the object actually belongs to; `module_path`\n        # is the allowlisted module it was resolved from, so a private C accelerator backing it\n        # (e.g. `io.StringIO` -> `_io`) is still accepted.\n        _check_resolved_module_allowed(resolved, declared_module=module_path)\n        # Refuse the deserializer's own machinery (the allowlist-administration function and the\n        # resolution helpers) on the class-resolution path too, so it cannot be reached as a\n        # component `type` or nested class reference. See `mark_deserialization_internal`.\n        _check_not_deserialization_internal(resolved, fully_qualified_name)\n        if module_path == \"builtins\":\n            _check_builtin_is_type(resolved, fully_qualified_name)\n        return resolved\n    except (ImportError, AttributeError) as error:\n        logger.exception(\"Failed to import '{full_name}'\", full_name=fully_qualified_name)\n        raise ImportError(f\"Could not import '{fully_qualified_name}'\") from error\n","sourceCodeStart":328,"sourceCodeEnd":347,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/utils/type_serialization.py#L328-L347","documentation":"_import_class_by_name() splits a dotted path, imports the module, and resolves the attribute; any ImportError or AttributeError is logged and re-raised as ImportError(f\"Could not import '{fully_qualified_name}'\"). Callers like deserialize_type convert it into DeserializationError. It means the dotted path is not importable in this environment.","triggerScenarios":"deserialize_type('pkg.mod.Class') where pkg.mod is missing, Class was renamed/removed, or an intermediate attribute doesn't exist; also reached via import_class_by_name.","commonSituations":"Deployment missing a dependency; version upgrade changed haystack's internal module layout; typos in fully qualified names in serialized pipelines.","solutions":["Verify the package providing the module is installed in the current environment (`pip show <pkg>` / install it)","Update the type string to the renamed class/module path for the current library version","Import the path manually to get the detailed underlying error (it's logged via logger.exception)","If it's a haystack internal path, switch to the documented public class"],"exampleFix":"// before\ndeserialize_type(\"haystack.components.converters.pypdf.PyPDFToText\")  # old path\n// after\ndeserialize_type(\"haystack.components.converters.pypdf.PDFMinerToText\")  # current path","handlingStrategy":"try-catch","validationCode":"def check_dotted(path):\n    try:\n        import_class_by_name(path)\n        return True\n    except ImportError:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    cls = import_class_by_name(fqn)\nexcept ImportError as e:\n    logger.error(\"Component %s unavailable: %s\", fqn, e)\n    cls = None  # or a substitute component","preventionTips":["Enable haystack logging to see the detailed underlying traceback","Check release notes for module/class renames when upgrading","Verify importability of every serialized type before deployment"],"tags":["python","import-error","deserialization","haystack"],"backgroundTag":"module-import-failed","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}