homebridge/homebridge · error
Plugin '${this.getPluginIdentifier()}' tried to register an
Error message
Plugin '${this.getPluginIdentifier()}' tried to register an accessory '${name}' which has already been registered! What it means
Plugin.registerAccessory() maintains a Map of accessory name -> constructor for the plugin. Calling api.registerAccessory() twice with the same accessory name is treated as a plugin bug (usually a double-initialization) and throws immediately instead of silently overwriting the first registration.
Source
Thrown at src/plugin.ts:109
}
this.loadContext = {
engines: packageJSON.engines,
dependencies: packageJSON.dependencies,
}
}
public getPluginIdentifier(): PluginIdentifier { // return full plugin name with scope prefix
return (this.scope ? `${this.scope}/` : '') + this.pluginName
}
public getPluginPath(): string {
return this.pluginPath
}
public registerAccessory(name: AccessoryName, constructor: AccessoryPluginConstructor): void {
if (this.registeredAccessories.has(name)) {
throw new Error(`Plugin '${this.getPluginIdentifier()}' tried to register an accessory '${name}' which has already been registered!`)
}
if (!this.disabled) {
log.info('Registering accessory \'%s\'', `${this.getPluginIdentifier()}.${name}`)
}
this.registeredAccessories.set(name, constructor)
}
public registerPlatform(name: PlatformName, constructor: PlatformPluginConstructor): void {
if (this.registeredPlatforms.has(name)) {
throw new Error(`Plugin '${this.getPluginIdentifier()}' tried to register a platform '${name}' which has already been registered!`)
}
if (!this.disabled) {
log.info('Registering platform \'%s\'', `${this.getPluginIdentifier()}.${name}`)
}
View on GitHub (pinned to edf5493034)
Solutions
- Search the plugin for duplicate api.registerAccessory() calls with the same name and remove/merge them.
- Guard registration with a module-level flag so the initializer only registers once.
- Ensure the plugin initializer is only invoked once per process (avoid re-requiring/re-executing the module).
- Check for duplicated name string literals — use a single exported constant for each accessory name.
Example fix
// before
export default (api) => {
api.registerAccessory('MyLight', MyLight)
api.registerAccessory('MyLight', MyLightAlt) // throws
}
// after
export default (api) => {
api.registerAccessory('MyLight', MyLight)
} Defensive patterns
Strategy: validation
Validate before calling
const registered = new Set()
function registerOnce(api, name, ctor) {
if (registered.has(name)) return
api.registerAccessory(name, ctor)
registered.add(name)
} Try / catch
try {
api.registerAccessory('MyLight', MyLight)
} catch (e) {
if (e instanceof Error && e.message.includes('already been registered')) {
log.warn('Accessory already registered; ignoring duplicate registration')
} else throw e
} Prevention
- Keep all api.registerAccessory() calls in one place in the initializer.
- Use an idempotence guard so re-running the initializer cannot double-register.
- Define accessory names as exported constants to avoid string duplicates.
When it happens
Trigger: A plugin's default export (initializer) calls api.registerAccessory('MyAccessory', ...) twice — e.g. the initializer runs twice, or the same name is registered conditionally in two branches that both execute.
Common situations: Hot-reload/dev setups that re-require the plugin module and re-run the initializer on the same API instance; copy-pasted registerAccessory calls with duplicate name strings; bundling issues where the plugin module is instantiated twice.
Related errors
- Plugin '${this.getPluginIdentifier()}' tried to register a p
- The requested accessory '${name}' was not registered by the
- ${context}: Matter accessory '${accessory.displayName}' (${a
- ${context}: Matter accessory '${accessory.displayName}' (${a
- ${context}: Matter accessory '${accessory.displayName}' (${a
AI-assisted analysis of homebridge/homebridge@edf5493034 (2026-08-30).
Data as JSON: /api/errors/ae19c0631e298e9d.
Report an issue: GitHub.