@@ -670,6 +670,53 @@ describe("PostgresRunStore", () => {
670670 }
671671 ) ;
672672
673+ postgresTest (
674+ "expireRunsBatch returns 0 and writes nothing when runIds is empty" ,
675+ async ( { prisma } ) => {
676+ const { organization, project, environment } = await seedEnvironment ( prisma ) ;
677+
678+ const store = new PostgresRunStore ( { prisma, readOnlyPrisma : prisma } ) ;
679+
680+ const runId = "run_expire_batch_empty" ;
681+ await prisma . taskRun . create ( {
682+ data : {
683+ id : runId ,
684+ engine : "V2" ,
685+ status : "PENDING" ,
686+ friendlyId : "run_expire_batch_empty_friendly" ,
687+ runtimeEnvironmentId : environment . id ,
688+ environmentType : "DEVELOPMENT" ,
689+ organizationId : organization . id ,
690+ projectId : project . id ,
691+ taskIdentifier : "my-task" ,
692+ payload : "{}" ,
693+ payloadType : "application/json" ,
694+ traceContext : { } ,
695+ traceId : "trace_empty" ,
696+ spanId : "span_empty" ,
697+ queue : "task/my-task" ,
698+ isTest : false ,
699+ taskEventStore : "taskEvent" ,
700+ depth : 0 ,
701+ } ,
702+ } ) ;
703+
704+ const error = { type : "STRING_ERROR" as const , raw : "unused" } ;
705+
706+ // Must not throw (Prisma.join([]) would build an invalid `IN ()` clause).
707+ const count = await store . expireRunsBatch ( [ ] , { error, now : new Date ( ) } ) ;
708+
709+ expect ( count ) . toBe ( 0 ) ;
710+
711+ const row = await prisma . taskRun . findUniqueOrThrow ( {
712+ where : { id : runId } ,
713+ select : { status : true , expiredAt : true } ,
714+ } ) ;
715+ expect ( row . status ) . toBe ( "PENDING" ) ;
716+ expect ( row . expiredAt ) . toBeNull ( ) ;
717+ }
718+ ) ;
719+
673720 postgresTest (
674721 "lockRunToWorker sets status to DEQUEUED with lock columns, includes runtimeEnvironment, and creates one PENDING_EXECUTING snapshot" ,
675722 async ( { prisma } ) => {
0 commit comments