homebridge/homebridge · error · TypeError
${pluginIdentifier} - ${platformName} attempt to unregister
Error message
${pluginIdentifier} - ${platformName} attempt to unregister an accessory that isn't PlatformAccessory! What it means
unregisterPlatformAccessories() applies the same instanceof guard before emitting UNREGISTER_PLATFORM_ACCESSORIES, since removing a non-PlatformAccessory from the bridge would corrupt accessory state. Passing anything other than real PlatformAccessory instances throws a TypeError.
Source
Thrown at src/api.ts:813
throw new TypeError(`${pluginIdentifier} - ${platformName} attempt to register an accessory that isn't PlatformAccessory!`)
}
accessory._associatedPlugin = pluginIdentifier
accessory._associatedPlatform = platformName
})
this.emit(InternalAPIEvent.REGISTER_PLATFORM_ACCESSORIES, accessories)
}
updatePlatformAccessories(accessories: PlatformAccessory[]): void {
this.emit(InternalAPIEvent.UPDATE_PLATFORM_ACCESSORIES, accessories)
}
unregisterPlatformAccessories(pluginIdentifier: PluginIdentifier, platformName: PlatformName, accessories: PlatformAccessory[]): void {
accessories.forEach((accessory) => {
// noinspection SuspiciousTypeOfGuard
if (!(accessory instanceof PlatformAccessory)) {
throw new TypeError(`${pluginIdentifier} - ${platformName} attempt to unregister an accessory that isn't PlatformAccessory!`)
}
})
this.emit(InternalAPIEvent.UNREGISTER_PLATFORM_ACCESSORIES, accessories)
}
/**
* Check if Matter is available in this version of Homebridge
* @returns true if Homebridge version satisfies >= 2.0.0-alpha.0
*/
isMatterAvailable(): boolean {
return semver.gte(this.serverVersion, '2.0.0-alpha.0')
}
/**
* Check if Matter is enabled for this bridge
* For main bridge: returns true if Matter is enabled in `bridge.matter` config
* For child bridge: returns true if Matter is enabled in the `_bridge.matter` configView on GitHub (pinned to edf5493034)
Solutions
- Keep references to the actual PlatformAccessory instances you registered and pass those to unregisterPlatformAccessories.
- Recreate a real PlatformAccessory via `new PlatformAccessory(name, uuid)` if the original was lost, then unregister it.
- Deduplicate @homebridge/hap-nodejs so instanceof checks match the host's class.
- Verify the array does not contain undefined entries (e.g. from a failed lookup filter).
Example fix
// before this.api.unregisterPlatformAccessories(pluginName, platformName, this.cache.map(a => JSON.parse(a))); // after const toRemove = this.cache.map(a => this.accessories.get(a.uuid)!).filter(a => a instanceof PlatformAccessory); this.api.unregisterPlatformAccessories(pluginName, platformName, toRemove);
Defensive patterns
Strategy: type-guard
Validate before calling
const valid = accessories.filter(a => a instanceof PlatformAccessory);
if (valid.length !== accessories.length) {
log.warn('Skipping non-PlatformAccessory items in unregister call');
} Type guard
function isPlatformAccessory(a: unknown): a is PlatformAccessory {
return a instanceof PlatformAccessory;
} Try / catch
try {
api.unregisterPlatformAccessories(plugin, platformName, accessories);
} catch (e) {
if (e instanceof TypeError && e.message.includes('unregister')) {
log.error('Only unregister accessories originally obtained from registration events');
}
} Prevention
- Subscribe to `api.on('didRegisterPlatformAccessories')` and store those exact instances for later unregistration.
- Never unregister accessories reconstructed from serialized state.
- Filter arrays with an instanceof guard before calling unregister.
- Deduplicate hap-nodejs copies so instanceof stays reliable.
When it happens
Trigger: Calling api.unregisterPlatformAccessories(pluginIdentifier, platformName, accessories) with plain objects, stale/foreign accessory copies, or items reconstructed from persisted JSON instead of the actual accessory objects returned by the `didRegisterPlatformAccessories` event or kept by the plugin.
Common situations: Dynamic platforms removing accessories after holding them in a custom cache that was serialized/deserialized; plugin reloads losing the original instances; duplicate hap-nodejs copies making instanceof fail.
Understand the failure class
Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.
Related errors
- ${pluginIdentifier} attempt to register an accessory that is
- ${pluginIdentifier} - ${platformName} attempt to register an
- ${cannotAction}: Matter is not enabled for this bridge. api.
- ${pluginIdentifier}: Cannot register Matter accessories yet
- Matter accessory "${accessory.displayName || 'unknown'}" is
AI-assisted analysis of homebridge/homebridge@edf5493034 (2026-08-30).
Data as JSON: /api/errors/aa78c8cad4cf43c9.
Report an issue: GitHub.