deepset-ai/haystack · error · ImportError

Could not import '{fully_qualified_name}'

Error message

Could not import '{fully_qualified_name}'

What it means

_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.

Source

Thrown at haystack/utils/type_serialization.py:346

        module = thread_safe_import(module_path)
        resolved = getattr(module, attr_name)
        # `_check_module_allowed` above gates the declared module path, which the caller controls.
        # A class/module re-exported as an attribute of an allowlisted module (e.g.
        # `haystack.utils.auth.os` -> the `os` module, or a re-exported `subprocess.Popen`) would
        # otherwise slip through. Re-check the module the object actually belongs to; `module_path`
        # is the allowlisted module it was resolved from, so a private C accelerator backing it
        # (e.g. `io.StringIO` -> `_io`) is still accepted.
        _check_resolved_module_allowed(resolved, declared_module=module_path)
        # Refuse the deserializer's own machinery (the allowlist-administration function and the
        # resolution helpers) on the class-resolution path too, so it cannot be reached as a
        # component `type` or nested class reference. See `mark_deserialization_internal`.
        _check_not_deserialization_internal(resolved, fully_qualified_name)
        if module_path == "builtins":
            _check_builtin_is_type(resolved, fully_qualified_name)
        return resolved
    except (ImportError, AttributeError) as error:
        logger.exception("Failed to import '{full_name}'", full_name=fully_qualified_name)
        raise ImportError(f"Could not import '{fully_qualified_name}'") from error

View on GitHub (pinned to e318778c9b)

Solutions

  1. Verify the package providing the module is installed in the current environment (`pip show <pkg>` / install it)
  2. Update the type string to the renamed class/module path for the current library version
  3. Import the path manually to get the detailed underlying error (it's logged via logger.exception)
  4. If it's a haystack internal path, switch to the documented public class

Example fix

// before
deserialize_type("haystack.components.converters.pypdf.PyPDFToText")  # old path
// after
deserialize_type("haystack.components.converters.pypdf.PDFMinerToText")  # current path
Defensive patterns

Strategy: try-catch

Validate before calling

def check_dotted(path):
    try:
        import_class_by_name(path)
        return True
    except ImportError:
        return False

Try / catch

try:
    cls = import_class_by_name(fqn)
except ImportError as e:
    logger.error("Component %s unavailable: %s", fqn, e)
    cls = None  # or a substitute component

Prevention

When it happens

Trigger: 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.

Common situations: Deployment missing a dependency; version upgrade changed haystack's internal module layout; typos in fully qualified names in serialized pipelines.

Related errors


AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30). Data as JSON: /api/errors/4be49bc6d6e2849b. Report an issue: GitHub.