mastra-ai/mastra · error · Error
Plugin id mismatch: registry has "${record.id}" but module e
Error message
Plugin id mismatch: registry has "${record.id}" but module exports "${plugin.id}" What it means
loadPluginRecord imports the plugin's entry module and compares its exported plugin.id against the id recorded in plugins.json. A mismatch means the registry entry and the module disagree — the loader refuses to load so tools are not registered under the wrong id. The plugin surfaces with status 'load failed'.
Source
Thrown at mastracode/sdk/src/plugins/loader.ts:67
loaded.push({ ...record, status: 'inactive', tools: {}, toolNames: [] });
continue;
}
loaded.push(await loadPluginRecord(record, options));
}
return markToolConflicts(loaded);
}
export async function loadPluginRecord(
record: ScopedInstalledPluginRecord,
options: LoadPluginRecordOptions,
): Promise<LoadedPlugin> {
try {
const entryPath = resolvePluginEntryPath(record, options);
const plugin = await importPluginModule(entryPath);
if (plugin.id !== record.id) {
throw new Error(`Plugin id mismatch: registry has "${record.id}" but module exports "${plugin.id}"`);
}
const configSchema = validatePluginConfigSchema(plugin.config);
const configValues = resolvePluginConfigValues(configSchema, record.config);
const pluginDir = path.dirname(entryPath);
const pluginRoot = resolvePluginRoot(record, options);
const context: MastraCodePluginContext = {
cwd: options.projectRoot,
scope: record.scope,
pluginDir,
config: configValues,
// Accessors, not instances: plugins load before the controller and the
// session exist, so a plugin resolves these when it needs them, not now.
getController: options.runtime?.getController,
getActiveSession: options.runtime?.getActiveSession,
};
const { tools, renderConfigs } = await resolvePluginTools(plugin, context);
const processors = await resolvePluginProcessors(plugin, context);View on GitHub (pinned to 75dd419e61)
Solutions
- Reinstall the plugin (or re-run the registry update) so plugins.json regenerates from the module's exported id.
- Align the exported plugin.id in the entry .ts with the record.id in plugins.json.
- Delete the stale record from plugins.json and re-add the plugin.
Example fix
// before (plugin.ts)
export const plugin = { id: 'my-plugin-v2', ... };
// registry: { "id": "my-plugin" }
// after
export const plugin = { id: 'my-plugin', ... }; // matches registry record id Defensive patterns
Strategy: validation
Validate before calling
import { loadPluginFromEntry } from '@mastra/code-sdk';
const plugin = await loadPluginFromEntry(entryPath); // throws before registry write
if (plugin.id !== expectedRecordId) {
throw new Error(`Regenerate registry: module exports "${plugin.id}", registry expects "${expectedRecordId}"`);
} Type guard
function isPluginWithId(value: unknown, id: string): value is { id: string } {
return typeof value === 'object' && value !== null && (value as { id?: unknown }).id === id;
} Try / catch
const loaded = await loadPluginRecord(record, options);
if (loaded.status === 'load failed' && loaded.error?.includes('Plugin id mismatch')) {
console.error(`Registry/module id drift for ${record.id}: reinstall the plugin or fix the exported id.`);
} Prevention
- Never hand-edit record.id in plugins.json; reinstall instead.
- When renaming a plugin id, reinstall so the registry regenerates.
- Run loadPluginFromEntry as a pre-publish check to confirm the exported id.
When it happens
Trigger: Renaming plugin.id in the source .ts after it was installed (registry still holds the old id); hand-editing record.id in plugins.json; installing a fork whose code exports a different id than the registered one; copying a plugin directory without updating its exported id.
Common situations: Upstream plugin renamed its id in a new release while the lockstep registry entry wasn't regenerated; manual tweaks to the registry file; duplicate installs where someone rebranded a plugin.
Related errors
- Plugin path for "${record.id}" must be inside the ${record.s
- Plugin entry for "${record.id}" must be inside the plugin di
- Repository link ${session.projectRepositoryId} is incomplete
- The server did not persist the requested settings
- Unsupported plugin entry extension "${path.extname(entryPath
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/ee9bc2caa7acb91b.
Report an issue: GitHub.