{"record":{"id":"520454278188053a","repo":"paperclipai/paperclip","slug":"plugin-migration-migrationkey-is-empty","errorCode":null,"errorMessage":"Plugin migration ${migrationKey} is empty","messagePattern":"Plugin migration (.+?) is empty","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/src/services/plugin-database.ts","lineNumber":500,"sourceCode":"          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,\n                namespaceName: namespace.namespaceName,\n                migrationKey,\n                checksum,\n                pluginVersion: manifest.version,\n                status: \"applied\",\n                appliedAt: new Date(),\n              })\n              .onConflictDoUpdate({","sourceCodeStart":482,"sourceCodeEnd":518,"githubUrl":"https://github.com/paperclipai/paperclip/blob/120ae5428fa29bee300bcf806491cd4d965fbb7c/server/src/services/plugin-database.ts#L482-L518","documentation":"Sanity guard in applyWithClient: the SQL migration file read from disk is empty after trimming. Empty migrations would create a misleading ledger row and checksum baseline, so they are rejected; the empty .sql file is at fault.","triggerScenarios":"Thrown at server/src/services/plugin-database.ts:500 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Add statements to the empty plugin migration, or remove the empty migration file."],"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-14T00:17:10.932Z"}