diff --git a/.server-changes/fix-batch-idempotency-per-item-keys.md b/.server-changes/fix-batch-idempotency-per-item-keys.md new file mode 100644 index 0000000000..9e84d474c3 --- /dev/null +++ b/.server-changes/fix-batch-idempotency-per-item-keys.md @@ -0,0 +1,6 @@ +--- +area: webapp +type: fix +--- + +Fix batchTrigger requests that set a per-item idempotency key failing with an error instead of creating and deduplicating the runs diff --git a/internal-packages/run-store/src/PostgresRunStore.ts b/internal-packages/run-store/src/PostgresRunStore.ts index b709857932..c206f4605f 100644 --- a/internal-packages/run-store/src/PostgresRunStore.ts +++ b/internal-packages/run-store/src/PostgresRunStore.ts @@ -72,6 +72,7 @@ export interface RunOpsCapableClient { // Standalone entity keyed by (environmentId, name); present on both schemas. waitpointTag: RunOpsDelegate<"upsert" | "findMany">; $queryRaw: PrismaClient["$queryRaw"]; + $queryRawUnsafe: PrismaClient["$queryRawUnsafe"]; $executeRaw: PrismaClient["$executeRaw"]; } @@ -1691,11 +1692,16 @@ export class PostgresRunStore implements RunStore { return []; } const prisma = (client ?? this.readOnlyPrisma) as RunOpsCapableClient; - const branches = args.idempotencyKeys.map( - (key) => - Prisma.sql`SELECT "friendlyId", "idempotencyKey", "idempotencyKeyExpiresAt" FROM "TaskRun" WHERE "runtimeEnvironmentId" = ${args.runtimeEnvironmentId} AND "taskIdentifier" = ${args.taskIdentifier} AND "idempotencyKey" = ${key}` + const params: string[] = []; + const branches = args.idempotencyKeys.map((key) => { + const base = params.length; + params.push(args.runtimeEnvironmentId, args.taskIdentifier, key); + return `SELECT "friendlyId", "idempotencyKey", "idempotencyKeyExpiresAt" FROM "TaskRun" WHERE "runtimeEnvironmentId" = $${base + 1} AND "taskIdentifier" = $${base + 2} AND "idempotencyKey" = $${base + 3}`; + }); + return prisma.$queryRawUnsafe( + branches.join(" UNION ALL "), + ...params ); - return prisma.$queryRaw(Prisma.join(branches, " UNION ALL ")); } // --- run-ops persistence ---