From 44fd1aa555a23698036c5439625b481a410aba42 Mon Sep 17 00:00:00 2001 From: Sean Whalen <44679+seanthegeek@users.noreply.github.com> Date: Mon, 27 Apr 2026 12:00:55 -0400 Subject: [PATCH] Coerce malformed in aggregate report metadata to None (#740) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit xmltodict turns stray angle brackets in (e.g. "") into a nested dict, which then flows through parse_aggregate_report_xml as the org_email value. Parsing succeeds, but Elasticsearch / OpenSearch reject the document at index time because the org_email mapping is text — observed as document_parsing_exception / mapper_parsing_exception with a "{#text=..., bad-xml=null}" preview. When report_metadata["email"] comes back as a dict, log it at debug and discard. The rest of the report still ingests with org_email=None instead of failing the whole document downstream. Co-authored-by: Sean Whalen Co-authored-by: Claude Opus 4.7 (1M context) --- parsedmarc/__init__.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/parsedmarc/__init__.py b/parsedmarc/__init__.py index 8b87b440..511b1b77 100644 --- a/parsedmarc/__init__.py +++ b/parsedmarc/__init__.py @@ -729,6 +729,12 @@ def parse_aggregate_report_xml( report = xmltodict.parse(xml)["feedback"] report_metadata = report["report_metadata"] + if isinstance(report_metadata.get("email"), dict): + logger.debug( + "Discarding malformed in report_metadata: %r", + report_metadata["email"], + ) + report_metadata["email"] = None schema = "draft" if "version" in report: schema = report["version"]