Model applies API changes without verifying version compatibility, causing silent runtime failures

Status Closed — not planned
Maintainer reply None cached
Activity 3 comments · opened Mar 30, 2026 · closed May 3, 2026

Bug Description

Claude introduced parser=safe_parser to lxml.etree.iterparse() calls as part of XXE security hardening. However, lxml 6.x does not support the parser= keyword argument for iterparse() — it raises TypeError.

Because the code was wrapped in try/except, this caused a silent failure: the XML import function reported "0 vouchers imported" instead of crashing, making the bug invisible to the user for 10 days.

Root Cause

Claude did not verify that iterparse() accepts a parser= kwarg in the installed lxml version (6.0.2). The model assumed iterparse() has the same API as etree.parse() / etree.fromstring(), which DO accept parser=.

Reproduction

  1. Ask Claude to add XXE protection to XML parsing code that uses lxml.etree.iterparse()
  2. Claude adds safe_parser = etree.XMLParser(recover=True, ...) and passes parser=safe_parser to iterparse()
  3. On lxml 5.x+/6.x, iterparse() does not accept parser= — it raises TypeError
  4. If wrapped in try/except, the failure is completely silent

Impact

  • XML file import feature silently broke (0 vouchers imported, no error shown)
  • User relied on the feature working and didn't notice for 10 days
  • The "security improvement" actually removed functionality

Correct Approach

iterparse() accepts security-relevant kwargs directly:

# WRONG (fails on lxml 6.x):
parser = etree.XMLParser(recover=True, resolve_entities=False, no_network=True)
context = etree.iterparse(filepath, parser=parser)  # TypeError!

# CORRECT:
context = etree.iterparse(filepath, recover=True, resolve_entities=False, no_network=True)

Suggested Model Improvements

  1. Verify API signatures before modifying function calls — especially when adding kwargs to library functions. Check docs or use introspection (help(), inspect.signature()).
  2. Test changes that touch try/except-wrapped code paths — silent failures are the worst kind. When modifying code inside try/except, add a quick verification that the change actually works.
  3. Don't assume uniform APIs across related functions — etree.parse(), etree.fromstring(), and etree.iterparse() have DIFFERENT signatures despite being in the same module.
  4. Flag silent failure risk — when modifying code wrapped in broad except, warn the user that failures will be invisible.

Environment

  • Python 3.13, lxml 6.0.2, Windows 11
  • Claude Code (Opus model)
  • The breaking commit was generated by Claude during an XXE protection hardening session

🤖 Generated with Claude Code

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗