Skip to content

Deleted products keep being pushed as updates with empty field lists — dead mappings never surface #12

Description

@Pichinov-Jose

Repository: SplashSync/Wordpress
Plugin version: 2.1.0 (code identical at current master HEAD)
WooCommerce: 11.0.1 · Target node: Dolibarr module 2.23.3

Summary

When a WooCommerce product disappears without deleted_post firing — a plugin removing rows directly,
a restore from backup, an integration rebuilding its own posts — the Splash link stays active. The
connector then keeps serving that object on every export, but with empty field lists. The target
node receives an update it cannot validate, logs an error, and the same error repeats on every
subsequent sync. Nothing ever reports that the source object is gone.

Concrete case

Dolibarr product EM-14239-8448 (id 984), one order and one invoice attached. On every export:

[Splash Client] Product Attribute Value Name is Not Valid.
  [product EM-14239-8448 (id 984) / attribute ticket] (received: '')

Checked on the WooCommerce side:

  • no product or variation carries the SKU EM-14239-8448, nor EM-14239;
  • all 404 attribute_ticket values in the database are non-empty — so the empty value is not a
    data problem;
  • the Events Manager event 14239 still exists and is published, but its WooCommerce product and its
    tickets are gone.

So the empty payload is not "bad data", it is "no data": the source object no longer exists, and the
connector still answers for it.

On this single install, 7 Dolibarr products are in this state. 5 of them carry sales, so the
target legitimately refuses to delete them — the link cannot resolve itself, and the error is
permanent.

Why deletion propagation does not cover this

Post\HooksTrait::deleted() does handle products correctly, dispatching by post type and using
getIdsForCommit() to expand a variable parent into its children. That path is fine.

The gap is everything that never reaches deleted_post: direct SQL deletion by another plugin,
database restores, or an integration that manages its own posts. In those cases the link survives
its source, and there is no mechanism to notice.

Suggested improvements

  1. Fail loudly instead of returning an empty object. When wc_get_product() returns nothing for
    a linked id, the object read should return an explicit "object not found" so the server can mark
    the link as dead — rather than handing the target an object whose lists are empty, which produces
    a partial write and a misleading validation error.
  2. Surface dead links. A read-only check in the self-tests — "N linked objects no longer exist on
    this node" — would make the problem visible and actionable, instead of appearing as recurring
    validation errors on unrelated fields.

Related: a duplicate SKU makes a mapping point at the wrong object

On the same install, five variable products each had one variation carrying the parent's own SKU
(price 0, never sold). The link therefore resolved to the target's variant base, so every write
returned:

[Splash Client] Luke, I am your father... This Product is a Variant base, so you cannot access it directly.

Deleting such a variation is worse than a failed write: it commits Product / SPL_A_DELETE, and the
link resolves to the parent on the target. On the Dolibarr side that is an unguarded deletion of a
product with 14 children and sales — reported separately as a data-loss issue on
SplashSync/Dolibarr (delete() lacks the variant-base guard that load() has).

Refusing to link — or at least warning — when a variation's SKU equals its parent's would remove the
trigger on this side, independently of the fix on the target side.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions