Main

Naming Entities So a Re-Pair Doesn’t Orphan Your Automations: unique_id Conventions That Survive Device Replacement

The failure mode: the automation still exists, the entity doesn’t

An automation references binary_sensor.kitchen_door. The contact sensor dies, you buy a replacement, pair it, and the automation keeps running — except the trigger never fires, because the entity it points at is now binary_sensor.kitchen_door_2, or a fresh registry entry with a new identity, while the old one sits unavailable. Nothing errors. The automation just stops matching.

The usual advice is to pick better entity names. That advice is backwards. The name is the part you can change safely. The part that must not change is the unique_id. If you get identity right, naming becomes cosmetic. If you get identity wrong, no naming convention saves you.

How the registry actually keys an entity

Home Assistant’s entity registry finds an entity by three things together: the domain (like sensor), the integration that provides it (like mqtt), and the unique ID. The unique ID only has to be unique within that combination. The developer documentation is blunt about the consequence: “The unique ID must never change, and users must not be able to change it. When it changes, Home Assistant sees a brand new entity, and everything the user set up for the old one is gone.”

That “everything” is the registry data you actually care about: the entity ID, the name, the icon, the area, whether it’s enabled, and any per-entity options. The same documentation says those settings “survive restarts, reinstalls of the device, and updates of your integration” — but only while the unique ID holds. An entity without a unique ID doesn’t get a registry entry at all, which means you can’t rename it, assign an area, or disable it from the interface.

So the mental model is simple: unique_id is the primary key. entity_id is a display alias stored against that key. Automations that reference entity_id are coupled to the alias, and the alias is stable exactly as long as the key is stable.

What the documentation says never to use as a unique ID

The Home Assistant developer docs list good sources — device serial number, MAC address formatted with format_mac, an identifier printed on the device or stored in firmware, a fixed location for place-based entities — and then a list of things never to use: “the IP address, the hostname, a URL, the name of the device, an email address, or a username. They all change.”

That list is the whole argument in one sentence. A unique ID derived from a name is a unique ID that changes when the name changes. A unique ID derived from a network address is a unique ID that changes when DHCP hands out a different lease. If your replacement device presents a different identity than the old one, the registry has no way to know it’s the same logical thing in the same place.

The three stacks fail differently — treat them separately

There is no single naming convention that covers MQTT discovery, ESPHome, and Z-Wave JS, because each one decides identity in a different place. A procedure that pretends otherwise will be wrong for at least one of them.

MQTT discovery: identity comes from the payload

For MQTT entities, the integration documentation states that if the unique_id option is configured, you can change the entity_id after creation and the change is stored in the registry. It also states that “to prevent multiple identical entries if a device reconnects, a unique identifier is necessary.” In other words, the discovery payload is the source of truth. Whatever the device or bridge publishes as unique_id is what the registry keys on.

Two details matter for replacement planning. First, the object_id in the discovery topic does not influence the resulting entity_id; default_entity_id is the option for that. Second, the documented best practice for entities with a unique_id is to set object_id to the unique ID and omit node_id. That keeps the topic structure aligned with identity rather than with a human label.

Zigbee2MQTT sits on top of this. Its documentation says the FRIENDLY_NAME in its MQTT topics is the IEEE address or, if defined, the friendly_name of a device or group. The bridge republishes zigbee2mqtt/bridge/devices whenever a device joins or leaves. A 2020 issue thread in the Zigbee2MQTT repository has the maintainer explaining that the 0x... portion of an entity ID is taken from friendly_name, that this is set once, and that when friendly_name is updated and discovery is resent, Home Assistant does not update the entity_id. I’m citing that as a historical statement about behavior, not as a claim about current versions — the retrieved sources don’t establish how any specific recent release constructs the discovery unique_id, and I won’t pretend otherwise.

What the sources do establish is that identity is fragile when it’s tied to a label. A community report describes exactly that: after removing and reinstalling the MQTT integration, the entity IDs of discovered devices changed, and the user “had to change every dashboard and automation.” That’s a different trigger than a re-pair, but the mechanism is the same — the registry saw new identities and created new entries.

ESPHome: identity is the device name, with an explicit migration path

ESPHome derives the entity ID from the entity name, which is a combination of the friendly name (or name if unset) and the component name. The integration documentation is explicit that each ESPHome device must have a unique name, and that this name matters for mDNS announcements, reconnection, and linking to the ESPHome Device Builder.

Because identity is name-based, ESPHome ships a documented replacement flow. Name Conflict Resolution triggers when the new device runs ESPHome 2025.4.0 or later, uses the same name (not just the friendly name), and the original device is offline. You then choose:

  • Migrate — transfers the existing entity configuration to the new device, preserving settings, entity names, and history. The docs recommend this when you’re replacing hardware but keeping the same YAML.
  • Overwrite — replaces the existing configuration with the new device, erasing the old device’s settings, entity names, customizations, and history.

The practical rule: if the replacement is the same logical device with the same YAML, keep the name identical and choose Migrate. If it’s genuinely a different device that happens to share a name, Overwrite is the honest choice. Choosing Migrate for a device that isn’t the same thing just carries stale history forward.

Z-Wave JS: identity lives on the adapter

Z-Wave is the easiest of the three to reason about, because the network identity is stored on the adapter, not in Home Assistant. The Z-Wave JS documentation says that when you migrate a Z-Wave network to a new adapter, “the Z-Wave integration with all its entities will stay in Home Assistant.” It also notes that while the mesh is permanently stored on the adapter, the additional metadata is not, and the integration interviews the entire network on first startup.

That means adapter replacement is a migration, not a re-pair. The entities persist because the devices never left the network. Re-including an individual device is a different operation and a different risk — and the retrieved Z-Wave JS page doesn’t document how entity unique IDs are constructed, so I’m not going to assert specifics about that here.

Diagnosing whether a re-pair orphaned anything

Don’t diagnose from the entity ID. A renamed entity and a replaced entity look similar on a dashboard and behave very differently underneath. Check the registry entry instead.

  1. Open the entity’s settings and look at the unique ID shown there. Compare it to what you recorded before the replacement. If it changed, you have a new registry entry, not a renamed one.
  2. Check the registry entry’s creation timestamp. A new created_at after a hardware swap confirms the registry treated the device as new.
  3. Look for the old entity. If it still exists and is unavailable, the automation is pointing at a ghost. If it’s gone entirely, the automation’s target no longer resolves.
  4. Check the integration’s own view of the device. For MQTT, the retained zigbee2mqtt/bridge/devices payload shows what the bridge currently believes is joined. For ESPHome, the device list shows whether the old device is still registered and offline.

This is the same discipline as auditing any small system that runs quietly in the background: verify the thing you think is running is the thing that’s actually registered. If you want a broader method for that, the audit walkthrough at How to Audit the Small Systems That Quietly Run Your Week covers the surrounding habit.

A pre-replacement checklist

Run this before you touch the hardware. It takes a few minutes and it’s the difference between a swap and an afternoon of re-pointing automations.

  1. Export the affected registry entries. For each entity on the device being replaced, record the entity ID, the unique ID, the integration, and the area. A screenshot of the entity settings page is enough; a text export is better.
  2. Confirm the replacement will present the same unique ID. For MQTT, that means the discovery payload must carry the same unique_id — which usually means pairing under the same identity the bridge used before. For ESPHome, it means flashing the same name and choosing Migrate. For Z-Wave, it means migrating the network rather than re-including devices.
  3. Prefer the integration’s migration path where one exists. ESPHome’s Migrate flow and Z-Wave’s adapter migration both exist precisely to preserve entity identity. Use them instead of deleting and re-adding.
  4. Replace the hardware, then verify. After the swap, re-check the unique IDs against your export. Only then confirm that automations still resolve — open each automation that referenced the device and check that its target entity is available, not just present.
  5. If the unique ID cannot be preserved, re-point deliberately. Update the automation to the new entity ID in one pass, and note which dashboards and scripts also referenced the old one. Don’t rename the new entity to match the old name and assume the automation will follow — the registry key is what the automation resolves against, not the label.

Naming conventions that actually help

Once identity is handled, naming is a separate, lower-stakes decision. A few conventions earn their keep:

  • Keep unique_id hardware-derived and immutable. Serial, MAC, or a firmware identifier. Never room, function, or a human label. Rooms change; the sensor doesn’t.
  • Keep entity_id human-readable and change it in the UI. The registry stores the change, and it survives restarts and integration updates as long as the unique ID holds. This is the layer where you encode “kitchen” and “door.”
  • Don’t encode location in the unique ID. If you move the sensor to another room, you want to change the label, not the identity.
  • For MQTT, follow the documented best practice: set object_id to the unique ID and omit node_id. It keeps the topic structure honest about what’s identity and what’s presentation.

Reducing the blast radius when identity does change

Sometimes the replacement genuinely can’t present the same unique ID — a different model, a different firmware, a bridge that generates a new identifier. In that case the goal shifts from prevention to containment.

The practical hedge is to reduce the number of places that hard-code an entity ID. Where your stack supports it, reference entities through scripts, labels, or area-targeted actions so a single identity change has a bounded set of references to update. This isn’t free — it adds indirection and makes some automations harder to read — so it’s a tradeoff, not a default. For a handful of critical automations, the indirection is worth it. For a one-off notification, hard-coding the entity ID is fine.

And it’s worth saying plainly: if the device is a dumb switch or a mechanical timer, none of this applies. A timer doesn’t have a registry entry to orphan. The engineering effort here is only justified for devices whose state actually feeds automations you’d notice breaking.

FAQ

Can I edit a unique ID in the Home Assistant UI?

No. The developer documentation states the unique ID must never change and users must not be able to change it. The supported path is to preserve the unique ID through the integration’s migration flow, or to accept a new registry entry and re-point references deliberately.

Why did my entity ID change after I renamed the device?

Entity IDs are generated once, when the entity is first loaded. For MQTT, the integration documentation says the entity_id is generated on first load and that default_entity_id controls it if set. Renaming a device later doesn’t retroactively rewrite an existing registry entry’s entity ID unless the integration explicitly does so. The 2020 Zigbee2MQTT thread documents exactly this: the maintainer states that when friendly_name is updated and discovery is resent, Home Assistant does not update the entity_id.

Does re-pairing a Zigbee device always create a new entity?

I can’t state that as a rule, because the retrieved sources don’t establish how current Zigbee2MQTT versions construct the discovery unique_id. What the sources do establish is the mechanism: if the discovery payload presents a different unique_id, the registry creates a new entry. Whether a given re-pair does that depends on the payload, so verify against the registry entry rather than assuming either way.

What’s the difference between Migrate and Overwrite in ESPHome?

Migrate transfers the existing entity configuration to the new device and preserves settings, entity names, and history. Overwrite replaces the existing configuration and erases the old device’s settings, entity names, customizations, and history. Use Migrate when the replacement is the same logical device with the same YAML; use Overwrite when it’s genuinely a different device.

Do I need to re-pair Z-Wave devices when I replace the adapter?

No. The Z-Wave JS documentation describes adapter migration as a procedure that keeps the integration and all its entities in Home Assistant. The mesh lives on the adapter, and the integration interviews the network on first startup. Re-including individual devices is a separate operation.