Hi everyone,
I've been working with the Copy Client process (MoveClient) in iDempiere v12 and I've run into several errors that I'd like to share with the community. I'm testing on the v12 seed database (minimal data), so in a real production DB with more data and customized tables, these errors will likely multiply.
My questions are at the bottom, but first I want to document what I found in case it's useful to others.
ENVIRONMENT
ERRORS FOUND (in order of appearance)
Error: "There is data in unsupported non-official data type for column AD_OrgInfo.C_Location_ID (refID=1000004)"
This error is triggered specifically by the AMERPSOFT Location Extended plugin. The plugin registers a custom reference (AD_Reference_ID > 999999) for the C_Location_ID column. The MoveClient process does not support custom references from plugins — it only recognizes official references with AD_Reference_ID <= 999999. When it finds a column with a higher refID, it checks if there's data in it and aborts with the above error, even though the column is a perfectly valid FK pointing to C_Location.
In short: custom plugin references (AD_Reference_ID > 999999) are not supported by MoveClient v12.
Workaround: Enable "Skip Some Validations" parameter. This bypasses the check but also skips other validations that may be important.
The process throws orphan errors on these columns during validateOrphan(). In iDempiere by design, CreatedBy and UpdatedBy have NO physical FK constraint in PostgreSQL. The process treats them as real FKs and fails with false positives.
Workaround: Enable "Skip Some Validations". This skips the entire validateOrphan() phase.
Note: errors 1 and 2 are both resolved by "Skip Some Validations". The following errors are not.
Error: "ERROR: duplicate key violates unique constraint ad_attachment_record. Key (ad_table_id, record_id)=(50008, 1000279) already exists"
When doing Copy Client within the same database, the source attachment record already exists and the converted Record_ID collides with it.
Workaround: Add AD_Attachment to "Tables to Exclude". Attachments won't be copied but the process continues.
Error: "Found orphan record in AD_Private_Access.Record_ID: 1000245 related to table C_Invoice"
AD_Private_Access is a polymorphic FK table (like AD_ChangeLog). It gets processed alphabetically before C_Invoice is inserted, so the FK resolution fails. AD_ChangeLog already has special treatment in canIgnoreNullConvertedId() but AD_Private_Access doesn't.
Workaround: Add AD_Private_Access to "Tables to Exclude".
This is probably the biggest usability issue: every run reveals exactly one error then stops. To discover all the problems you have to run the process N times. There's no way to get a complete picture of all conflicts in a single pass.
No workaround found for this one.
Error: "ERROR: duplicate key violates unique constraint c_currencyisocode. Key (iso_code)=(usd) already exists"
System currencies (USD, EUR, etc.) already exist in the target DB. The process tries to re-insert them and aborts.
Workaround: Add C_Currency to "Tables to Exclude". Currency references still resolve correctly since currency IDs are system-level (< 999999).
STRUCTURAL OBSERVATIONS (not a complaint, just feedback for the community)
After going through all of this, I think some of these behaviors are worth discussing as potential improvements:
Tables are inserted in alphabetical order (ORDER BY TableName), not in FK dependency order. This is the root cause of most orphan errors since parent tables aren't guaranteed to be inserted before child tables.
Custom plugin references (AD_Reference_ID > 999999) are not supported at all. There is no mechanism to recognize plugin-registered FKs as valid, which makes the process incompatible out of the box with any environment that has third-party plugins extending the dictionary.
There's no handling for unique constraint violations on INSERT. The process only accounts for FK orphans but not for cases where system data (currencies, UOMs, countries) already exists in the target DB.
The fail-fast behavior makes diagnosis very slow when there are multiple issues. A "collect all errors and report at end" mode would help enormously, especially when working with the seed DB where you discover issues one by one per run.
Audit columns (CreatedBy, UpdatedBy) and certain system tables (AD_Session, AD_ChangeLog, AD_Package_Imp*, AD_PInstance*) have no default exclusion in code, putting the burden entirely on the user to configure the right exclusion list.
The pre-validation phase (validate()) and execution phase (moveClient()) detect different problems with partially duplicated logic, so passing validation doesn't guarantee a clean execution.
MY QUESTIONS
For errors 3, 4, 5 and 6 described above, the only workaround I found is adding the affected tables to "Tables to Exclude". Is that really the only option without modifying the code, or is there something else I'm missing?
Is there a recommended or official exclusion list for a typical Copy Client operation in v12? I know the wiki mentions some tables but I haven't found a comprehensive one that covers system tables like AD_Attachment, AD_Private_Access, C_Currency and similar.
Has anyone else hit these issues on production DBs? With real data volumes I imagine the list of affected tables grows significantly beyond what I'm seeing with the seed DB.
Regarding the fail-fast behavior — every run reveals exactly one error then stops, making diagnosis extremely slow. Is there any known trick or parameter to get a full picture of all conflicts in a single run without modifying the code?
Is there an open ticket or active discussion about improving the resilience of this process? I noticed Carlos Ruiz (globalqss) has a dedicated repo for MoveClient — is that the right place to follow up or should I open a ticket in the official tracker?
Thanks in advance, any input is appreciated.
--