Skip to main content

Integration Errors

The Integration Errors screen is the failure-analysis tool over the validation table (F564236). It surfaces every entry recorded by the validation pipeline — from XSD / Schematron rule failures to lifecycle-level integration errors (PDF, PA, DB, …) — and presents them through two complementary views:

  • by-rule — ranked cards grouped by (rule, source), each card showing how many invoices the rule has touched plus per-severity chips. The fastest way to spot which rule is biting hardest right now.
  • by-event — flat table of every individual error event, with severity, source, rule, message, document triplet and the invoice's current status. The right place to investigate one specific row.

The page applies regardless of source system — JD Edwards, SAP, NetSuite or a custom ERP. The errors come from the validation pipeline, which itself works on the generated UBL, so the source format is transparent here.

Refreshed in 2026.05.4

Previously the page was the orphan-error view only — a flat table of F564236 rows that had no matching invoice header. It is now a proper failure-analysis tool: by-rule + by-event toggle, a category filter (UBL vs Integration / lifecycle), human descriptions extracted from the bundled Schematron files, and an Unmatched only checkbox that keeps the orphan-error behaviour one click away. Default view is all errors — orphans are no longer the main filter.


Opening the page

  • Sidebar → Application → Integration Errors.
  • From the Dashboard: the Top failing rules widget's View all link opens this page on the by-rule tab; clicking a specific rule lands on the by-event tab with that rule pre-applied as a filter chip.

At a glance

Integration ErrorsBy ruleBy eventAll sources ▾☐ Unmatched only↻ RefreshAllFATALERRORWARNINGINFOBR-CL-23EN1693152CurrencyCode must use the ISO 4217three-character code list.ERROR · 50WARNING · 2BR-FR-12CIUSFR38SIRET BT-46 must be present on aFrench B2B invoice.ERROR · 38PA_SENDINTEG14PA submission rejected at HTTPlevel (timeout / 4xx / 5xx).ERROR · 14UBL_CREATIONINTEG9XSL transform did not producea parseable UBL document.FATAL · 9By-event view (preview)SEV · DOC · DCT · KCO · SEQN · SOURCE · RULE · MESSAGEERROR · 12345 · RI · 00070 · 7 · CIUSFR · BR-FR-12 · SIRET missingERROR · 12345 · RI · 00070 · 12 · EN16931 · BR-CL-23 · CurrencyCode invalidFATAL · 12399 · RI · 00070 · 1 · INTEG · UBL_CREATION · XSL transform threwWARNING · 12345 · RI · 00070 · 18 · CIUSFR · BR-FR-09 · BT-49 missing on cred…View toggleBy rule / By eventCategory filterUBL vs IntegrationSeverity chipsFATAL / ERROR / WARN / INFORule cardcode · source · count · severityRule descriptionextracted from .sch filesLifecycle codesPA_SEND, UBL_CREATION, …Click → invoice modalopens on the History tab

The rule cards are sized via CSS auto-fill instead of auto-fit, so a short last row no longer stretches a single card to the full row width.


Toolbar

The same toolbar drives both views.

ControlBehaviour
View toggleBy rule (default after a deep-link from the dashboard) or By event. Other filters carry across — switching tabs keeps the search, severity and category filters intact.
SearchSubstring match against DOC, DCT, KCO and the message text. Server-side, debounced.
CategoryAll sources (default), UBL validation (Schematron / XSD rules — UVSRCL IN ('EN16931', 'CIUSFR', 'FREXTIC', 'CPRO', 'XSD', 'UBL')), Integration / lifecycle (everything else — runtime errors emitted by the dispatcher: PDF, PA, DB, …).
Severity chipsAll / FATAL / ERROR / WARNING / INFO. One severity at a time; clicking the active chip resets to All.
Unmatched only (by-event only)Restores the orphan-only behaviour of the previous version — keeps just the rows that have no joined invoice header. Off by default; one click away when needed.
RefreshRe-runs the current query.

Advanced Filters (2026.05.10)

A collapsible Advanced Filters panel below the toolbar exposes one row per filterable column from the active List Views spec (view.integration-errors) — with per-column operator pickers (contains, equals, , <, , >, , between, empty, not empty). Edits stay in draft until Run commits them.

The Tech Dashboard's Recent errors drill-through also surfaces here: when the dashboard passes { doc, dct, kco }, a chip shows the active drill-through filter and offers a one-click × clear. Useful when the panel is collapsed and the filter would otherwise stay invisible.

Since 2026.05.12 the page runs in hybrid client-side mode — one capped server slice per Run (spec.maxRows, default 5000), then TanStack handles filter / sort / paginate inside the slice. An X / Y rows notice next to Run signals when the cap is hit. Since 2026.05.13, the invoiceStatus refList column gets a multi-select picker that issues an IN (?,?,?) clause on the server so picking several statuses returns the union.


By-rule view

Each card groups every error event sharing the same (rule, source) pair and shows:

ElementSourceMeaning
Rule code (top left)UVY56RULEThe rule identifier — e.g. BR-CL-23, BR-FR-12, UBL_CREATION.
Source (below the code)UVSRCLThe validation engine — EN16931, CIUSFR, FREXTIC, CPRO, XSD, UBL, or one of the integration buckets (INTEG, PROCESS, XSL, PDF, PA, DB, …).
Description (secondary line)ValidationRuleCatalogHuman description, in the user's UI language when available.
Count (top right)aggregated COUNT(DISTINCT doc, dct, kco)Number of invoices touched by this rule in the active filters.
Severity chips (bottom)aggregated (level, count)Per-severity breakdown — FATAL · n, ERROR · n, WARNING · n, INFO · n.

Cards are sorted by descending count; clicking one switches to the by-event view with that rule pre-applied as a filter chip.

Where the descriptions come from

In 2026.05.4 the page started decorating rule codes with the human description of each rule, so a code like BR-CL-23 no longer needs to be cross-referenced against an external Schematron file.

A new ValidationRuleCatalog parses the bundled .sch files at first call and extracts a {rule id → description} map by matching [<id>]<separator><description> lines inside each <assert> block. The separator is permissive (- or :, optional surrounding whitespace) and covers the three formats in the four bundled schematrons:

SchematronFormatExample
EN 16931[<id>]-<description> (no spaces)[BR-CL-23]-Currency code must follow ISO 4217.
FREXT-IC[<id>] - <description> (spaces)[BR-FREXT-IC-08] - SIRET must be present on B2B.
CIUS-FR[<id>] : <description> (colon, plus FNFE-MPE convention)[BR-FR-23/BT-49] : Document is missing the order reference.

The catalogue also seeds twelve lifecycle / integration rule codes with French descriptions: UBL_CREATION, DB_INSERT, DB_UPDATE, PA_SEND, PA_TIMEOUT, PDF_RENDER, XSL_TRANSFORM, EMAIL_SEND, NOTIFY_DISPATCH, STATUS_TRANSITION, EXTRACT_BIP, EXTRACT_FTP — these are the codes emitted by ErrorCatalog when a runtime step fails.

The merged catalogue is exposed on GET /api/integration-errors/catalog; the frontend caches it once per page load via the useRuleCatalog hook.

Known gap

The BR-FR-CPRO schematron's 34 asserts have no id attribute, so the validator records empty rule codes for them — the corresponding events appear in the by-event view with an empty Rule column and are absent from the by-rule cards. The schematron itself works; only the rule labels are missing.


By-event view

A flat table, one row per validation event. The default sort is by document key ascending (so the same invoice's rows stay grouped) and pagination defaults to 50 rows per page.

Since 2026.05.10 the table renders through DataTableV2 in spec-driven mode: the column shape comes from the view.integration-errors spec on db-nomaubl and the bundled default ships every column listed below. Adding columns from the catalog or trimming the filter allow-list is done from the List Views editor.

ColumnSourceDescription
SeverityUVY56LEVELColoured badge — FATAL / ERROR / WARNING / INFO.
Date (2026.05.9)UVUPMJ + UVUPMTDate and time the event was recorded. Same time context as the Tech Dashboard's recent-errors card, so triage no longer requires opening a row first.
DocUVDOCDocument number from the source data.
DctUVDCTDocument type.
KcoUVKCOCompany code.
SeqUVSEQNSequence number — the order in which validation rules fired during the failed run.
SourceUVSRCLValidation engine — EN16931, CIUSFR, FREXTIC, CPRO, XSD, UBL, or an integration bucket.
RuleUVY56RULERule identifier. The cell shows the code + the description below it (and as a tooltip on hover).
Invoice nowF564231 lookupThe invoice's current status, joined live so you see whether the failure has been re-processed. Empty when no invoice header exists (orphan error).
CustomerF564231.UHALPHCustomer name when the invoice exists. Helpful when triaging by counterparty.
Message column dropped — 2026.05.9

The Message column was removed in 2026.05.9. Schematron / XPath messages were too long for a grid cell (the column was eating ~720 px and still cut off context), so the full message now lives in a detail modal opened by clicking the row. The modal also splits the CTC-FR debug context (Num Fact: …, Code: S, rate: 20, …) from the French explanation — the explanation becomes the main line, the debug fields render as a small monospace grid underneath.

Clicking a row

The row click is always actionable since 2026.05.9 — both matched and orphan rows open a modal:

  • Matched rows (where the invoice exists in F564231) open the full E-Invoicing detail modal on the History tab — same modal the inbox row click on Notifications uses. The lifecycle, the validation errors and the PA payload sit one tab away.
  • Unmatched / orphan rows open the new ErrorDetailModal — a focused view sized to a single validation event with no surrounding invoice. It shows: the level badge, the rule identifier + description (resolved through useRuleCatalog), the source, the date, the doc / dct / kco triplet (with a no matching invoice in F564231 hint), the customer when known, and the full message rendered through the same splitValidationMessage helper as the matched-row modal.

Unmatched only

A small checkbox in the toolbar — Unmatched only — restores the previous version's behaviour: only the rows that have no joined invoice header. These are orphan errors, typically transformation failures that prevented the invoice from ever being persisted (the XSL produced something the UBL validator could not parse, or a FATAL aborted the pipeline before the database insert).

The default view shows every error, matched or not. Switching the checkbox on is one click; nothing else is needed.


How to investigate

The page is read-only — the actual fix happens upstream (source data, template, XSL, connector) and a re-run clears the row. A typical investigation:

  1. Open the by-rule view first. Look at the top three cards — one rule with hundreds of hits is the obvious starting point.
  2. Scope the category. UBL validation surfaces only Schematron / XSD events; Integration / lifecycle surfaces only the runtime errors the dispatcher emits. Mixing them only helps when you are looking for a specific document.
  3. Click the rule to switch to By event with the filter chip pre-applied. The list now shows every invoice that hit the rule.
  4. Click a row to open the invoice's History tab. The validation errors, the lifecycle and the PA payload all sit there.
  5. Read the message + the rule description. The description gives the what; the message gives the where (which field, which line). For Schematron rules, cross-reference with the Reason Codes page when needed.
  6. Open the source XML in UBL Tools → XML Viewer for the (doc, dct, kco) triplet — the file lives in dirInput/<template>/. Reading the source confirms whether the failure is data-side (missing field) or template-side (XSL bug).
  7. Re-run the pipeline once the source is fixed. Use Process Document on the corrected file. Once the invoice is successfully persisted, Invoice now shifts on this page from empty to the new status, and the row stops being orphan.

Tips & best practices

  • Start with by-rule. A single rule with hundreds of hits points to one upstream change (a renamed field, a stale tax code, a regenerated counterparty list). Fixing the rule typically clears most rows on this page in one re-run.
  • Use the category filter to triage. UBL validation failures are usually template / XSL bugs; Integration / lifecycle errors are usually environment / connector issues (PA outage, SMTP timeout, DB lock). Knowing which side you are on cuts the investigation time in half.
  • Watch FATAL first. A non-zero FATAL means the pipeline aborted — the invoice was never persisted at all and only the orphan row exists. ERROR rows mean the invoice may have made it partway and the regular E-Invoicing page also carries something for them.
  • Unmatched only is the legacy view. The previous version of this page only ever showed orphans. Toggle the checkbox on to restore that behaviour for compatibility — the by-rule view, the category filter and the rule descriptions all keep working.
  • Errors auto-disappear after a successful re-import. Once the invoice header is created or updated, the row's Invoice now column reflects the new status. Orphan rows (no header at all) similarly stop being orphan once a successful run lands. The underlying entry stays in F564236 for audit, but it leaves the unmatched set.
  • Deep-links from the dashboard save a step. The Top failing rules widget on the Dashboard lands here pre-filtered — a one-click drill from "this rule is biting" to "show me the events".