{"record":{"id":"93064555edb45ce8","repo":"homebridge/homebridge","slug":"tried-to-initialize-a-plugin-which-hasn-t-been-loa","errorCode":null,"errorMessage":"Tried to initialize a plugin which hasn't been loaded yet!","messagePattern":"Tried to initialize a plugin which hasn't been loaded yet!","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/plugin.ts","lineNumber":245,"sourceCode":"      // initializer\". Helps plugin authors and users diagnose ESM/CJS\n      // shape mismatches at a glance.\n      const exportedKeys = pluginModule && typeof pluginModule === 'object'\n        ? Object.keys(pluginModule).filter(k => k !== 'default').slice(0, 10)\n        : []\n      const defaultKeys = pluginModules && typeof pluginModules === 'object'\n        ? Object.keys(pluginModules).slice(0, 10)\n        : []\n      const defaultKeysStr = defaultKeys.length > 0 ? ` with keys [${defaultKeys.join(', ')}]` : ''\n      const exportedKeysStr = exportedKeys.length > 0 ? `; named exports: [${exportedKeys.join(', ')}]` : ''\n      throw new Error(\n        `Plugin ${this.pluginPath} does not export an initializer function from ${this.main}. Found default export of type '${typeof pluginModules}'${defaultKeysStr}${exportedKeysStr}. The plugin must default-export a function that takes the homebridge api object.`,\n      )\n    }\n  }\n\n  public initialize(api: API): void | Promise<void> {\n    if (!this.pluginInitializer) {\n      throw new Error('Tried to initialize a plugin which hasn\\'t been loaded yet!')\n    }\n\n    return this.pluginInitializer(api)\n  }\n}\n","sourceCodeStart":227,"sourceCodeEnd":251,"githubUrl":"https://github.com/homebridge/homebridge/blob/edf54930340d67cade23d01abd41b03cd9621e8b/src/plugin.ts#L227-L251","documentation":"Plugin.initialize() is called after Plugin.load() has resolved the initializer function. If the plugin hasn't been loaded (load() never ran or threw earlier without surfacing), this.pluginInitializer is undefined and initialize() throws. This indicates an internal sequencing bug or a swallowed load failure.","triggerScenarios":"PluginManager calls plugin.initialize(api) on a Plugin instance whose load() step was skipped or failed; this.pluginInitializer remains undefined because load() never completed.","commonSituations":"Framework-level race/bug in plugin loading; user code constructing Plugin manually and calling initialize() first; a load() error caught and ignored upstream leaving the plugin half-initialized.","solutions":["Ensure load() completes before initialize(); in normal usage just restart Homebridge and check startup logs for an earlier plugin load error.","Run Homebridge in debug mode (-D) and look for the underlying load failure (e.g. bad engines, bad main path) that left the plugin unloaded.","If you build tooling against these internals, always await/sequence plugin.load(...) before plugin.initialize(api).","Report to homebridge/homebridge with debug logs if it occurs on a standard startup with no prior errors."],"exampleFix":"// before: tool code\nconst plugin = new Plugin(...)\nawait plugin.initialize(api)\n// after\nconst plugin = new Plugin(...)\nawait plugin.load()\nawait plugin.initialize(api)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await plugin.initialize(api)\n} catch (e) {\n  if ((e as Error).message.includes(\"hasn't been loaded\")) {\n    log.error('Plugin load step was skipped or failed — check earlier logs')\n  }\n}","preventionTips":["Always call load() before initialize() when using these internals directly.","Watch startup debug logs for swallowed load errors.","Keep Homebridge updated; report reproducible cases upstream.","Don't construct Plugin instances manually in tooling without replicating the full lifecycle."],"tags":["plugin","lifecycle","internal-state"],"backgroundTag":"plugin-not-loaded","analyzedSha":"edf54930340d67cade23d01abd41b03cd9621e8b","analyzedAt":"2026-08-30T21:28:53.235Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}