immich-app/immich · error
No loaded plugin found for
Error message
No loaded plugin found for ${pluginKey} What it means
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.
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
Example fix
// before
await pluginRepo.callMethod({ pluginKey: 'geo-plugin', methodName: 'geocode' });
// after
await pluginRepo.load({ key: 'geo-plugin', label: 'Geo' /* ... */ });
await pluginRepo.callMethod({ pluginKey: 'geo-plugin', methodName: 'geocode' }); Defensive patterns
Strategy: validation
Validate before calling
// assume repo exposes loaded keys or track them yourself
if (!loadedPluginKeys.has(pluginKey)) {
throw new Error(`Plugin '${pluginKey}' not loaded — call load() first`);
} Try / catch
try {
return await pluginRepo.callMethod({ pluginKey, methodName }, input);
} catch (e) {
if (String(e.message).startsWith('No loaded plugin found')) {
logger.error(`Plugin ${pluginKey} unavailable (not loaded or failed to load)`);
return fallbackResult(methodName, input);
}
throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Asset media not found
- Asset metadata is not yet ready for streaming
- Asset not found
- Asset not found
- Asset not found or asset is not a video
AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15).
Data as JSON: /api/errors/a5f23b0fd4c21f9d.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/repositories/plugin.repository.ts:247
},
),
destroy: (plugin) => plugin.close(),
},
{ min: 1, max: 5 },
);
try {
await pool.ready();
this.pluginMap.set(key, { pool, label });
} catch (error: Error | any) {
throw new Error(`Unable to instantiate plugin: ${key}`, { cause: error });
}
}
async callMethod<T>({ pluginKey, methodName }: PluginMethod, input: unknown, context?: unknown) {
const item = this.pluginMap.get(pluginKey);
if (!item) {
throw new Error(`No loaded plugin found for ${pluginKey}`);
}
const { pool, label } = item;
try {
const plugin = await pool.acquire();
try {
const result = await plugin.call(methodName, JSON.stringify(input), context);
return (result ? result.json() : result) as T;
} finally {
await pool.release(plugin);
}
} catch (error: Error | any) {
throw new Error(`Plugin method call failed: ${label}#${methodName}`, { cause: error });
}
}
}
View on GitHub (pinned to e55ac299a4)