Skip to content

Incoming invoice import fails: saxonche GraalVM crash (cron/forked worker) + prefix-less UBL not parsed #9

@thib-d

Description

@thib-d

Context

Setting up incoming invoice import (reception) with l10n_fr_einvoicing + l10n_fr_einvoicing_import against the SuperPDP sandbox on Odoo 18. Two blockers prevent an incoming flow from becoming a draft vendor bill. Sending works fine.

Versions: l10n_fr_einvoicing 18.0.1.0.1, pyfrctc 0.10, saxonche 13.0.0, Odoo 18, Python 3.12.

1. Fatal GraalVM/saxonche crash during import (process abort)

When the import cron (fr.einvoicing.flow._in_cronpyfrctc.parse_cdar_cdar_check_schematron) runs, Saxon-C aborts the process:

graal_create_isolate error
Fatal error: Failed to enter the specified IsolateThread context. (code 2)

saxonche (Saxon-C/GraalVM) binds its isolate to the thread/process that first initializes the runtime. Odoo imports it at startup (main thread) then calls it from a cron/worker thread (workers=0) or a forked worker (workers>0) → crash. In threaded mode this kills the whole Odoo process (pod restart / crash-loop).

Minimal repro: python3 -c "import os; os.fork() or __import__('saxonche').PySaxonProcessor()" → child aborts.

Reported on pyfrctc: akretion/pyfrctc#3. Fix that works: run the Saxon XSLT transform in a fresh subprocess (fork+exec), e.g. by replacing saxonche.PySaxonProcessor with a subprocess-backed shim (also covers the factur-x library, which uses Saxon the same way).

2. Prefix-less UBL not parsed (secondary, OCA edi)

SuperPDP's generate_test_invoice?format=ubl (and presumably some senders) emit valid UBL that redeclares the default namespace on every element (no cbc:/cac: prefixes). OCA account_invoice_import_ubl.parse_ubl_invoice derives its XPath namespace map from xml_root.nsmap, which then lacks cbc/cac:

File ".../account_invoice_import_ubl/wizard/account_invoice_import.py", line 134, in parse_ubl_invoice
    ubl_version_xpath = xml_root.xpath("//cbc:UBLVersionID", namespaces=namespaces)
lxml.etree.XPathEvalError: Undefined namespace prefix

This belongs to OCA/edi account_invoice_import_ubl, but it surfaces here when receiving via the PDP. Workaround: normalize the tree to declare standard cbc:/cac: prefixes at the root before parsing (or make the parser's namespaces map URI-based instead of document-derived).

Result after both fixes

Incoming flow → draft vendor bill created correctly (number, HT/VAT/TTC, lines). Happy to open PRs (subprocess shim for pyfrctc; namespace normalization for OCA edi) if useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions