{"record":{"id":"f2053c2c81e462c1","repo":"deepset-ai/haystack","slug":"could-not-import-callable-handle-as-a-module-o","errorCode":null,"errorMessage":"Could not import '{callable_handle}' as a module or callable.","messagePattern":"Could not import '(.+?)' as a module or callable\\.","errorType":"exception","errorClass":"DeserializationError","httpStatus":null,"severity":"error","filePath":"haystack/utils/callable_serialization.py","lineNumber":171,"sourceCode":"        # The module check also does not stop import primitives that live inside an allowlisted\n        # namespace (e.g. `haystack...thread_safe_import`), which are gateways to code execution\n        # equivalent to the denied builtin `__import__`. Block them too.\n        _check_not_denied_callable(attr_value, callable_handle)\n\n        # Refuse the deserializer's own machinery — the allowlist-administration function\n        # (`allow_deserialization_module`) and the resolution helpers (`deserialize_callable`,\n        # `deserialize_type`, `import_class_by_name`). They live in the allowlisted `haystack`\n        # namespace, so the module checks above admit them, but resolving them from serialized data\n        # lets a hostile pipeline register them as Jinja custom filters, disarm the allowlist with\n        # `'*'`, and then resolve and invoke arbitrary callables such as `os.system`.\n        _check_not_deserialization_internal(attr_value, callable_handle)\n\n        return attr_value\n\n    # Nothing on the allowlist was importable. Surface the standard allowlist error when the\n    # top-level module is untrusted; otherwise report a plain resolution failure.\n    _check_module_allowed(callable_handle)\n    raise DeserializationError(f\"Could not import '{callable_handle}' as a module or callable.\")\n","sourceCodeStart":153,"sourceCodeEnd":172,"githubUrl":"https://github.com/deepset-ai/haystack/blob/e318778c9bf60a1963e3b5f451359655dd696c30/haystack/utils/callable_serialization.py#L153-L172","documentation":"deserialize_callable exhausted every resolution strategy against the module allowlist and still could not import the handle, so after emitting the standard allowlist error it raises DeserializationError. Neither the top-level module nor any dotted path could be resolved to a callable.","triggerScenarios":"from_dict/deserialize_callable with a handle whose module is not importable (not installed, wrong PYTHONPATH) or not on the deserialization allowlist, or a malformed dotted path.","commonSituations":"Loading a pipeline referencing a third-party package not installed in the current environment; custom components module not on sys.path; module blocked by haystack's safe-deserialization allowlist; typos in module names.","solutions":["Install the missing package or add your module to sys.path/PYTHONPATH","Ensure the module is trusted/allowlisted for haystack deserialization (configure the allowlist mechanism)","Fix typos in the serialized callable handle","Verify importability with importlib.import_module on the top-level module"],"exampleFix":"// before\npython -c \"import my_custom_components\"  # ModuleNotFoundError\n// after\npip install -e .  # or export PYTHONPATH=/path/to/project","handlingStrategy":"try-catch","validationCode":"import importlib\n\ndef module_importable(handle: str) -> bool:\n    try:\n        importlib.import_module(handle.split(\".\")[0])\n        return True\n    except ImportError:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    pipeline = Pipeline.loads(yaml_str)\nexcept DeserializationError as e:\n    if \"Could not import\" in str(e):\n        handle = extract_handle(str(e))\n        logger.error(\"install missing package or allowlist module for %s\", handle)\n    raise","preventionTips":["Ensure all packages referenced by a pipeline are installed in the target environment","Add custom component modules to the deserialization allowlist when required","Keep PYTHONPATH/sys.path correct in deployment environments","Prefer importing haystack-provided component paths over ad-hoc handles"],"tags":["python","deserialization","import","module-allowlist","haystack"],"backgroundTag":"module-import-failed","analyzedSha":"e318778c9bf60a1963e3b5f451359655dd696c30","analyzedAt":"2026-08-30T11:45:20.711Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}