langchain-ai/langchain · error · OutputParserException
Failed to parse XML format from completion {text}. Got: {e}
Error message
Failed to parse XML format from completion {text}. Got: {e} What it means
OutputParserException raised by XMLOutputParser.parse when et.fromstring raises ParseError: after extracting optional fenced code blocks and encoding declarations and stripping whitespace, the text is still not well-formed XML. The original text is attached via llm_output for debugging.
Source
Thrown at libs/core/langchain_core/output_parsers/xml.py:251
et = ElementTree # Use the defusedxml parser
else:
et = ET # Use the standard library parser
match = re.search(r"```(xml)?(.*)```", text, re.DOTALL)
if match is not None:
# If match found, use the content within the backticks
text = match.group(2)
encoding_match = self.encoding_matcher.search(text)
if encoding_match:
text = encoding_match.group(2)
text = text.strip()
try:
root = et.fromstring(text)
return self._root_to_dict(root)
except et.ParseError as e:
msg = f"Failed to parse XML format from completion {text}. Got: {e}"
raise OutputParserException(msg, llm_output=text) from e
@override
def _transform(self, input: Iterator[str | BaseMessage]) -> Iterator[AddableDict]:
streaming_parser = _StreamingParser(self.parser)
for chunk in input:
yield from streaming_parser.parse(chunk)
streaming_parser.close()
@override
async def _atransform(
self, input: AsyncIterator[str | BaseMessage]
) -> AsyncIterator[AddableDict]:
streaming_parser = _StreamingParser(self.parser)
async for chunk in input:
for output in streaming_parser.parse(chunk):
yield output
streaming_parser.close()
View on GitHub (pinned to e32fa9a52e)
Solutions
- Use XMLOutputParser's get_format_instructions()/prompt template so the model sees the exact expected format and encoding
- Increase max_tokens so closing tags are not truncated
- Catch OutputParserException, inspect llm_output, and retry with corrective feedback or strip non-XML prefix/suffix before re-parsing
Example fix
# before
prompt = "Give me people and their favorite foods in XML."
chain = prompt | llm | XMLOutputParser()
# after
parser = XMLOutputParser()
prompt = PromptTemplate(
template="Answer the user query.\n{format_instructions}\n{query}",
input_variables=["query"],
partial_variables={"format_instructions": parser.get_format_instructions()},
)
chain = prompt | llm | parser Defensive patterns
Strategy: retry
Validate before calling
import re
def looks_like_xml(text: str) -> bool:
text = text.strip()
m = re.search(r"```(?:xml)?(.*)```", text, re.DOTALL)
if m:
text = m.group(1)
return bool(re.search(r"<[a-zA-Z:_][^>]*>", text)) Try / catch
from langchain_core.exceptions import OutputParserException
try:
out = parser.invoke(text)
except OutputParserException as e:
raw = e.llm_output # original text for repair
out = parser.invoke(f"<filtered>{strip_non_xml(raw)}</filtered>") # repair & retry Prevention
- Always inject parser.get_format_instructions() into the prompt
- Ensure max_tokens covers the full XML including closing tags
When it happens
Trigger: LLM returns malformed XML: unclosed tags, XML-ish prose without a single root element, markdown bullet fragments like '- <tag>value' where '-' precedes the root, multiple sibling root elements, or unescaped & characters.
Common situations: Prompting 'return XML' without an example; models wrapping XML in explanations; truncation by max_tokens cutting the closing tag; special characters (&, <) not escaped in values.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Arguments 'observation' & 'llm_output' are required if 'send
- Expected exactly one result, but got {len(result)}
- Could not parse function call data: {exc}
- Function {raw_tool_call['function']['name']} arguments: {ar
- {exceptions joined with '\n\n'}
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/6e6a7372c21ba5e5.
Report an issue: GitHub.