{"record":{"id":"ee9bc2caa7acb91b","repo":"mastra-ai/mastra","slug":"plugin-id-mismatch-registry-has-record-id-bu","errorCode":null,"errorMessage":"Plugin id mismatch: registry has \"${record.id}\" but module exports \"${plugin.id}\"","messagePattern":"Plugin id mismatch: registry has \"(.+?)\" but module exports \"(.+?)\"","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"mastracode/sdk/src/plugins/loader.ts","lineNumber":67,"sourceCode":"      loaded.push({ ...record, status: 'inactive', tools: {}, toolNames: [] });\n      continue;\n    }\n\n    loaded.push(await loadPluginRecord(record, options));\n  }\n\n  return markToolConflicts(loaded);\n}\n\nexport async function loadPluginRecord(\n  record: ScopedInstalledPluginRecord,\n  options: LoadPluginRecordOptions,\n): Promise<LoadedPlugin> {\n  try {\n    const entryPath = resolvePluginEntryPath(record, options);\n    const plugin = await importPluginModule(entryPath);\n    if (plugin.id !== record.id) {\n      throw new Error(`Plugin id mismatch: registry has \"${record.id}\" but module exports \"${plugin.id}\"`);\n    }\n\n    const configSchema = validatePluginConfigSchema(plugin.config);\n    const configValues = resolvePluginConfigValues(configSchema, record.config);\n    const pluginDir = path.dirname(entryPath);\n    const pluginRoot = resolvePluginRoot(record, options);\n    const context: MastraCodePluginContext = {\n      cwd: options.projectRoot,\n      scope: record.scope,\n      pluginDir,\n      config: configValues,\n      // Accessors, not instances: plugins load before the controller and the\n      // session exist, so a plugin resolves these when it needs them, not now.\n      getController: options.runtime?.getController,\n      getActiveSession: options.runtime?.getActiveSession,\n    };\n    const { tools, renderConfigs } = await resolvePluginTools(plugin, context);\n    const processors = await resolvePluginProcessors(plugin, context);","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/sdk/src/plugins/loader.ts#L49-L85","documentation":"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'.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (plugin.ts)\nexport const plugin = { id: 'my-plugin-v2', ... };\n// registry: { \"id\": \"my-plugin\" }\n// after\nexport const plugin = { id: 'my-plugin', ... }; // matches registry record id","handlingStrategy":"validation","validationCode":"import { loadPluginFromEntry } from '@mastra/code-sdk';\nconst plugin = await loadPluginFromEntry(entryPath); // throws before registry write\nif (plugin.id !== expectedRecordId) {\n  throw new Error(`Regenerate registry: module exports \"${plugin.id}\", registry expects \"${expectedRecordId}\"`);\n}","typeGuard":"function isPluginWithId(value: unknown, id: string): value is { id: string } {\n  return typeof value === 'object' && value !== null && (value as { id?: unknown }).id === id;\n}","tryCatchPattern":"const loaded = await loadPluginRecord(record, options);\nif (loaded.status === 'load failed' && loaded.error?.includes('Plugin id mismatch')) {\n  console.error(`Registry/module id drift for ${record.id}: reinstall the plugin or fix the exported id.`);\n}","preventionTips":["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."],"tags":["plugin-loading","registry","id-mismatch","consistency"],"backgroundTag":"plugin-id-mismatch","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}