Skip to content

adapter: second diff crashes after syncing LAG member interfaces #167

Description

@estivate

What happens

After a successful synchronization creates physical interfaces with a bundle
relationship to a LAG, the next diff or sync fails while loading the Infrahub
destination.

The destination contains the complete relationship, but extraction receives a shallow
representation of the referenced InterfaceLag without its device identity component.
The command exits before producing a plan:

PeerIdentifierError: Cannot build unique_id for peer InterfaceLag
(relationship InterfacePhysical.bundle): missing identifier key(s) ['device'];
required identifiers=['device', 'name']

The failure occurs during destination extraction, before a plan is created or any
destination write is attempted. No data corruption has been observed.

What should happen

A destination populated by a previous successful synchronization must remain loadable.
Subsequent diff and sync commands should preserve the physical-interface-to-LAG
relationship and report no create or update operations for converged rows.

Steps to reproduce

  1. Start with a clean Infrahub destination and load the required schema.

  2. Create a bounded NetBox synchronization project whose InterfacePhysical mapping
    includes this field:

    - name: bundle
      mapping: lag
      reference: InterfaceLag
  3. Generate the project:

    uv run infrahub-sync generate \
      --name bounded-netbox \
      --directory /path/to/sync-projects
  4. Run the first authorized synchronization. It succeeds and creates physical interfaces,
    including at least one whose bundle points to an InterfaceLag:

    uv run infrahub-sync sync \
      --name bounded-netbox \
      --directory /path/to/sync-projects
  5. Start a fresh command and load the converged destination again:

    uv run infrahub-sync diff \
      --name bounded-netbox \
      --directory /path/to/sync-projects
  6. Observe that destination extraction exits with PeerIdentifierError instead of
    producing a converged diff.

The failure can also be reproduced by loading only the Infrahub destination; it does not
depend on constructing or contacting the NetBox source adapter.

Why it fails

The Infrahub adapter populates one shared SDK node store while loading mapped kinds in
order. It first stores a fully hydrated InterfaceLag, including the device relationship
required by the DiffSync identity. Loading InterfacePhysical later stores a different,
shallow representation of that same LAG from the nested bundle payload. UUID lookup then
returns the shallow object, whose missing device relationship is not detected by the
adapter's scalar-attribute completeness check.

This is primarily an Infrahub adapter correctness issue: the adapter knows the peer's
required identity fields and must not build an identity from an incomplete stored node.
The SDK store's replacement semantics are a secondary hardening boundary.

Environment

  • infrahub-sync main:
    9edc1bc59fb55284094370c5686c3e2aa5f5ac4b (direct live reproduction)
  • infrahub-sync feature/v3-develop:
    8ba0c57a7601bd0ffc75431488d6b59717217de6 (confirmed by the earlier live
    reproduction on descendant 645d5f4a666de3afe81411c59948f5c0b136549d; the
    Infrahub adapter and SDK lock are identical across that range)
  • infrahub-sdk: 1.18.1
  • Extraction mode: full extraction
  • Destination schema: schema-library bgi-schema-library-v2

Workaround

Removing InterfacePhysical.bundle from the mapping allows destination extraction to
complete, but LAG membership is then no longer synchronized.

sync --continue-on-error is not a convergence workaround: it skips the peer relationship
and can produce phantom relationship updates.

References

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions