{"record":{"id":"a5f23b0fd4c21f9d","repo":"immich-app/immich","slug":"no-loaded-plugin-found-for-pluginkey","errorCode":null,"errorMessage":"No loaded plugin found for ${pluginKey}","messagePattern":"No loaded plugin found for (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/src/repositories/plugin.repository.ts","lineNumber":247,"sourceCode":"            },\n          ),\n        destroy: (plugin) => plugin.close(),\n      },\n      { min: 1, max: 5 },\n    );\n\n    try {\n      await pool.ready();\n      this.pluginMap.set(key, { pool, label });\n    } catch (error: Error | any) {\n      throw new Error(`Unable to instantiate plugin: ${key}`, { cause: error });\n    }\n  }\n\n  async callMethod<T>({ pluginKey, methodName }: PluginMethod, input: unknown, context?: unknown) {\n    const item = this.pluginMap.get(pluginKey);\n    if (!item) {\n      throw new Error(`No loaded plugin found for ${pluginKey}`);\n    }\n\n    const { pool, label } = item;\n\n    try {\n      const plugin = await pool.acquire();\n      try {\n        const result = await plugin.call(methodName, JSON.stringify(input), context);\n        return (result ? result.json() : result) as T;\n      } finally {\n        await pool.release(plugin);\n      }\n    } catch (error: Error | any) {\n      throw new Error(`Plugin method call failed: ${label}#${methodName}`, { cause: error });\n    }\n  }\n}\n","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/immich-app/immich/blob/e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c/server/src/repositories/plugin.repository.ts#L229-L265","documentation":"callMethod looks up the plugin by pluginKey in the repository's pluginMap; if no plugin with that key was ever loaded (or it failed to load and was never registered), it throws 'No loaded plugin found for <pluginKey>'. This is a lookup/lifecycle error — the method call cannot proceed.","triggerScenarios":"callMethod({pluginKey, methodName}) is invoked with a pluginKey that is absent from pluginMap — typo in key, plugin load failed earlier, plugin not loaded yet (race before load completes), or plugin was unloaded.","commonSituations":"Key renamed in code but callers still use the old name; startup ordering issue where a feature calls the plugin before load() finishes; earlier 'Unable to instantiate plugin' left the plugin unregistered; environment where the plugin is intentionally not deployed.","solutions":["Confirm load() succeeded for that pluginKey before calling callMethod (check startup logs)","Verify the exact pluginKey string matches the one passed to load()","Add an existence check or registry query before invoking callMethod","Fix startup ordering so dependent services wait for plugin loading to complete"],"exampleFix":"// before\nawait pluginRepo.callMethod({ pluginKey: 'geo-plugin', methodName: 'geocode' });\n// after\nawait pluginRepo.load({ key: 'geo-plugin', label: 'Geo' /* ... */ });\nawait pluginRepo.callMethod({ pluginKey: 'geo-plugin', methodName: 'geocode' });","handlingStrategy":"validation","validationCode":"// assume repo exposes loaded keys or track them yourself\nif (!loadedPluginKeys.has(pluginKey)) {\n  throw new Error(`Plugin '${pluginKey}' not loaded — call load() first`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await pluginRepo.callMethod({ pluginKey, methodName }, input);\n} catch (e) {\n  if (String(e.message).startsWith('No loaded plugin found')) {\n    logger.error(`Plugin ${pluginKey} unavailable (not loaded or failed to load)`);\n    return fallbackResult(methodName, input);\n  }\n  throw e;\n}","preventionTips":["Centralize plugin keys in a shared constants module to avoid typos","Gate feature code on plugin readiness (await load / ready event) at startup","Alert on plugin load failures so unregistered plugins are noticed before calls","Expose a health endpoint listing currently loaded plugin keys"],"tags":["plugin","lifecycle","not-found"],"backgroundTag":"resource-not-found","analyzedSha":"e55ac299a4ec7cb372e35dbf2c6c05ee9ce77f6c","analyzedAt":"2026-09-15T07:20:19.675Z","contentChangedAt":"2026-09-15T07:20:19.675Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}