@@ -390,7 +390,7 @@ export class RunJob {
390390 throw caughtError ;
391391 } finally {
392392 if ( shouldQueueNextJob && ! isJobExtendedToSubscriberSchedule ) {
393- await this . tryQueueNextJobs ( job , notification ) ;
393+ await this . tryQueueNextJobs ( job , notification , ! ! error ) ;
394394 } else if ( ! isJobExtendedToSubscriberSchedule ) {
395395 // Update workflow run status based on step runs when halting on step failure
396396 await this . workflowRunService . updateDeliveryLifecycle ( {
@@ -469,8 +469,16 @@ export class RunJob {
469469 * Attempts to queue subsequent jobs in the workflow chain.
470470 * If queueNextJob.execute returns undefined, we stop the workflow.
471471 * Otherwise, we continue trying to queue the next job in the chain.
472+ *
473+ * @param hasCurrentJobError - If true, the current job failed with an error. When the workflow
474+ * ends (no next job), we skip creating the status trace here and let setJobAsFailed handle it
475+ * to avoid duplicate traces and ensure correct error status.
472476 */
473- private async tryQueueNextJobs ( job : JobEntity , notification ?: PartialNotificationEntity | null ) : Promise < void > {
477+ private async tryQueueNextJobs (
478+ job : JobEntity ,
479+ notification ?: PartialNotificationEntity | null ,
480+ hasCurrentJobError = false
481+ ) : Promise < void > {
474482 let currentJob : JobEntity | null = job ;
475483 let nextJob : JobEntity | null = null ;
476484 if ( ! currentJob ) {
@@ -491,16 +499,18 @@ export class RunJob {
491499 } ) ;
492500
493501 if ( ! nextJob ) {
494- // Update workflow run status when there is no next job (workflow complete)
495- await this . workflowRunService . updateDeliveryLifecycle ( {
496- workflowStatus : WorkflowRunStatusEnum . COMPLETED ,
497- notificationId : currentJob . _notificationId ,
498- environmentId : currentJob . _environmentId ,
499- organizationId : currentJob . _organizationId ,
500- _subscriberId : currentJob . _subscriberId ,
501- notification,
502- currentJob : { type : currentJob . type , _id : currentJob . _id } ,
503- } ) ;
502+ if ( ! hasCurrentJobError ) {
503+ // Update workflow run status when there is no next job (workflow complete successfully)
504+ await this . workflowRunService . updateDeliveryLifecycle ( {
505+ workflowStatus : WorkflowRunStatusEnum . COMPLETED ,
506+ notificationId : currentJob . _notificationId ,
507+ environmentId : currentJob . _environmentId ,
508+ organizationId : currentJob . _organizationId ,
509+ _subscriberId : currentJob . _subscriberId ,
510+ notification,
511+ currentJob : { type : currentJob . type , _id : currentJob . _id } ,
512+ } ) ;
513+ }
504514
505515 return ;
506516 }
@@ -589,15 +599,15 @@ export class RunJob {
589599 ) ;
590600
591601 const isHaltingWorkflow = shouldHaltOnStepFailure ( nextJob ) && ! this . shouldBackoff ( error as Error ) ;
592- const isLastJobInWorkflow = ! jobAfterNext || isHaltingWorkflow ;
602+ const isLastJobFailed = ! jobAfterNext || isHaltingWorkflow ;
593603
594604 await this . setJobAsFailed . execute (
595605 SetJobAsFailedCommand . create ( {
596606 environmentId : nextJob . _environmentId ,
597607 jobId : nextJob . _id ,
598608 organizationId : nextJob . _organizationId ,
599609 userId : nextJob . _userId ,
600- isLastJobInWorkflow ,
610+ isLastJobFailed ,
601611 } ) ,
602612 error as Error
603613 ) ;
0 commit comments