langchain-ai/langchain · error · ImportError

defusedxml is not installed. Please install it to use the…

Error message

defusedxml is not installed. Please install it to use the defusedxml parser. You can install it with `pip install defusedxml`. See https://github.com/tiran/defusedxml for more details

What it means

ImportError raised in _StreamingParser.__init__ when parser='defusedxml' is requested but the optional defusedxml package is not installed. The streaming XML parser needs defusedxml's XMLParser to protect against entity-expansion and other XML attacks, so it refuses to fall back silently to the unsafe stdlib parser.

Solutions

  1. Install defusedxml: pip install defusedxml (or add it to your project dependencies)
  2. If you intentionally parse fully trusted input only, construct XMLOutputParser with the standard-library parser option instead of parser='defusedxml'
  3. Pin defusedxml in requirements/uv.lock so CI and prod match

Example fix

# before (ImportError at runtime)
parser = XMLOutputParser(parser="defusedxml")

# after
# shell: pip install defusedxml
parser = XMLOutputParser(parser="defusedxml")  # now works
Defensive patterns

Strategy: validation

Validate before calling

import importlib.util
if parser_name == "defusedxml" and importlib.util.find_spec("defusedxml") is None:
    raise ImportError("install defusedxml before using the defusedxml XML parser")

Prevention

When it happens

Trigger: Constructing XMLOutputParser(parser='defusedxml') (the default) in an environment where defusedxml is not installed — langchain-core does not depend on it unconditionally.

Common situations: Deploying to slim containers/lambda images that installed langchain-core without the xml extra; upgrading langchain versions where the optional dependency was pruned from the lockfile.

Related errors


AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14). Data as JSON: /api/errors/2e4760231170d610. Report an issue: GitHub.

Appendix: source

Thrown at libs/core/langchain_core/output_parsers/xml.py:70

        Args:
            parser: Parser to use for XML parsing.

                Can be either `'defusedxml'` or `'xml'`. See documentation in
                `XMLOutputParser` for more information.

        Raises:
            ImportError: If `defusedxml` is not installed and the `defusedxml` parser is
                requested.
        """
        if parser == "defusedxml":
            if not _HAS_DEFUSEDXML:
                msg = (
                    "defusedxml is not installed. "
                    "Please install it to use the defusedxml parser. "
                    "You can install it with `pip install defusedxml`. "
                    "See https://github.com/tiran/defusedxml for more details"
                )
                raise ImportError(msg)
            parser_ = XMLParser(target=TreeBuilder())
        else:
            parser_ = None
        self.pull_parser = ET.XMLPullParser(["start", "end"], _parser=parser_)
        self.xml_start_re = re.compile(r"<[a-zA-Z:_]")
        self.current_path: list[str] = []
        self.current_path_has_children = False
        self.buffer = ""
        self.xml_started = False

    def parse(self, chunk: str | BaseMessage) -> Iterator[AddableDict]:
        """Parse a chunk of text.

        Args:
            chunk: A chunk of text to parse. This can be a `str` or a `BaseMessage`.

        Yields:
            A `dict` representing the parsed XML element.

View on GitHub (pinned to e32fa9a52e)