The reason ERP migrations slip is measurable. In Panorama's 2024 ERP Report, data issues were cited by 34.9% of the projects that ran over budget and 46.3% of those that ran late, a top-four cause of both. Those data issues are rarely the raw rows failing to move. They are the meaning that failed to move with them. What follows is where that meaning hides, why it decides whether the new system reconciles, and how to recover it before go-live.
The export is not the problem
Ask a program owner what worries them about the migration and getting the data out is rarely the first answer. Modern ERPs, even old ones sitting on a SQL Server database, will give you the tables. The worry is what the tables mean. A field called status holds the integer 3, and only the old system, or the person who configured it in 2014, knows that 3 means released to production but not yet invoiced. A custom field added during an implementation five years ago drives a calculation that half the reports depend on. None of this is recorded in documentation. It is embedded in the software's behaviour, and maybe in a few people's heads, if they still work at the company.
Cryptic raw order status codes.
One manufacturer described this to us while planning their move to a new ERP. Their assessment was blunt: not everything the old vendor modelled is mapped or explained anywhere, so they expected to have to work around it. For a real ERP migration, that is the normal state of affairs.
What "undocumented mapping" actually covers
"Business logic" is vague enough to ignore until it is too late, so it helps to be specific. In practice it is three recurring things:
- Status and type codes. Every ERP encodes the state of an order, a delivery, or an invoice as a code, and what each code means is a local decision. Moving to a new system means someone has to say which old code maps to which new one, and that is a business judgement rather than a lookup.
- Custom fields. Almost every real deployment has fields added after go-live to capture something the standard model missed. They often feed calculations or filters that matter, and they are the least documented part of the system precisely because they were added under time pressure.
- Derived and workflow logic. The old system did not just store data, it applied rules. This order type skips a step, that customer gets a different tax treatment, this document cannot post until another one exists. Some of that logic has to survive the move, and it is invisible in a raw export.
Why it stays undocumented
None of this is negligence. ERP vendors model this behaviour inside their software as a matter of course, and they have little reason to write a plain-language explanation of every customer-specific configuration. The people who made the configuration decisions move on. The knowledge that remains is distributed across the team as habit rather than held anywhere you can read. For a system that has run the business for a decade, the documentation is the running system.
Recovering the logic in a form you can check
The way Beetl approaches this is to treat the old system's data and behaviour as the source of truth, and to reconstruct the mapping from it rather than from a document that does not exist. We read the tables, look at how values actually distribute, and propose a mapping: this old code corresponds to this new one, this custom field feeds this rule.
Transform raw data into comprehensible data with mapping logic.
The part that matters is that the proposal is inspectable. We use AI to draft the mapping definition, because reading through years of accumulated configuration is exactly the kind of work LLMs are best for, but the output is a definition a person can read and approve rather than a black box that transforms the data invisibly. Someone who knows the business looks at the proposed mapping, corrects the cases the data alone cannot settle, and signs it off. The integration does not disappear into an opaque agent. It becomes an explicit, versioned artefact that says what the migration will do.
Reconciliation is the test
A recovered mapping is only trustworthy if the numbers hold. For each group of records, the customers, the products, the open orders, the receivables, the totals on the old side and the new side have to tie out, and the exceptions have to be explained rather than rounded away. That reconciliation is how you know the undocumented logic was actually captured and not quietly dropped. A migration that loads without errors but does not reconcile has usually lost exactly the business logic this piece is about.
Before: 2 rows carry a status code with no approved mapping, so the group fails loudly instead of loading silently.
After: The unmapped code is resolved, and one row stays in review for a person to settle.
Keeping the transformation explicit and the result reconcilable, rather than trusting a step you cannot see into, is how we think about data work in general, not only in a migration.
The takeaway
If you are scoping an ERP migration, put the budget on the mapping rather than the export. The raw data will move. What decides whether the new system tells the truth is whether the undocumented logic came with it, and whether you can check that it did. The data issues that show up in a third of over-budget migrations are rarely the raw rows. They are the logic that moved without its meaning. The most useful thing we can do on a migration is turn that hidden logic into something explicit, reviewable, and reconciled before anyone depends on it.
