Skip to content

Bridge serves an EMPTY aggregator after restart — Apple resets rooms on every reboot #141

Description

@simons-plugins

The defect

After any bridge-node restart the node comes online with zero child endpoints and stays that way until the plugin connects and attaches. Measured on jarvis after a full reboot:

10:59:30.177  indigo-matter-bridge is online        <- aggregator EMPTY
10:59:53.198  Client attached, reconciling 4 endpoint(s)
10:59:53.773  Endpoint 287885105  added as number 3
...

23 seconds advertising as a bridge with no accessories. Apple reconnects inside that window, reads an empty PartsList, and concludes every accessory has gone. When they reappear it treats them as new arrivals: assigned to the bridge's own room, with metadata the user can no longer edit ("cannot change settings").

Why this is the root cause

It is the only theory consistent with every observation:

Observation Explained by
Rooms broke after the E5 plugin/node upgrade node restart → empty window
A fresh unpair + re-pair fixed them accessories present from the moment of pairing
Rooms broke again after a full reboot node restart → empty window
A newly exported device was roomable added while the node was up; never vanished
…but broke once un-exported and re-exported Apple saw that one endpoint vanish and return

Three earlier theories were tested and disproved (no-Matter-traffic; un-export identity reuse; configurationVersion reset — matter.js does persist and restore it). This one is measured, not inferred.

Impact

Every restart of the bridge node — reboot, plugin upgrade, agent restart, crash recovery — costs the user their room assignments for all exported accessories, and they cannot be set again without a full unpair/re-pair cycle. That is the single most user-visible defect in the export feature.

Fix

The node must never serve an empty aggregator. It should reconstruct its last-known endpoint set at startup, independently of the plugin, with reachable: false until the plugin attaches and confirms real state. Apple then sees a bridge whose accessories were briefly unreachable — a state it handles routinely — rather than a bridge that lost everything.

Implementation notes:

  • endpoint-map.json already persists identity (uniqueId → endpoint number) and already survives factoryReset. It needs the role and label too so an endpoint can be rebuilt without the plugin.
  • Restore before server.start() so the node is never online-and-empty.
  • The plugin's attach remains authoritative: it reconciles the restored set, which is what removes anything genuinely un-exported while the plugin was away.
  • Watch the interaction with §3.1's mass-removal guard — a restored set the plugin then legitimately empties must still be refused without intent: replace_all.
  • reachable: false on restore also makes XAC8 honest: accessories show as unavailable until the plugin is actually driving them.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions