{"record":{"id":"06923ae6daefc7c2","repo":"paperclipai/paperclip","slug":"plugin-migration-checksum-mismatch-for-migration","errorCode":null,"errorMessage":"Plugin migration checksum mismatch for ${migrationKey}","messagePattern":"Plugin migration checksum mismatch for (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/src/services/plugin-database.ts","lineNumber":492,"sourceCode":"      const migrationFiles = await listSqlMigrationFiles(migrationDir);\n      const coreReadTables = manifest.database.coreReadTables ?? [];\n      const lockKey = Number.parseInt(createHash(\"sha256\").update(pluginId).digest(\"hex\").slice(0, 12), 16);\n      const persistFailure = options.persistFailure ?? true;\n\n      const applyWithClient = async (client: PluginDatabaseClient) => {\n        await client.execute(sql`SELECT pg_advisory_xact_lock(${lockKey})`);\n        for (const migrationKey of migrationFiles) {\n          const content = await readFile(path.join(migrationDir, migrationKey), \"utf8\");\n          const checksum = createHash(\"sha256\").update(content).digest(\"hex\");\n          const existingRows = await client\n            .select()\n            .from(pluginMigrations)\n            .where(and(eq(pluginMigrations.pluginId, pluginId), eq(pluginMigrations.migrationKey, migrationKey)))\n            .limit(1);\n          const existing = existingRows[0] as PluginMigrationRecord | undefined;\n          if (existing?.status === \"applied\") {\n            if (existing.checksum !== checksum) {\n              throw new Error(`Plugin migration checksum mismatch for ${migrationKey}`);\n            }\n            continue;\n          }\n\n          const statements = splitSqlStatements(content);\n          try {\n            if (statements.length === 0) {\n              throw new Error(`Plugin migration ${migrationKey} is empty`);\n            }\n            for (const statement of statements) {\n              validatePluginMigrationStatement(statement, namespace.namespaceName, coreReadTables);\n              await client.execute(sql.raw(statement));\n            }\n            await client\n              .insert(pluginMigrations)\n              .values({\n                pluginId,\n                pluginKey: manifest.id,","sourceCodeStart":474,"sourceCodeEnd":510,"githubUrl":"https://github.com/paperclipai/paperclip/blob/120ae5428fa29bee300bcf806491cd4d965fbb7c/server/src/services/plugin-database.ts#L474-L510","documentation":"Immutability guard in applyWithClient: the migration file's content hash no longer matches the checksum recorded when it was first applied. Editing applied migration files is forbidden (it makes environments diverge), so re-apply aborts; the modified migration file is at fault.","triggerScenarios":"Thrown at server/src/services/plugin-database.ts:492 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Restore the migration file to match the recorded checksum, or repair the migration history intentionally."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"120ae5428fa29bee300bcf806491cd4d965fbb7c","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}