@@ -818,21 +818,21 @@ async function executeWebhookJobInternal(
818818 throw new Error ( `Workflow ${ payload . workflowId } has no associated workspace` )
819819 }
820820
821- return withResourceOutboundScope ( { workspaceId } , async ( ) => {
822- const workflowVariables = ( workflowRecord . variables as Record < string , unknown > ) || { }
821+ const workflowVariables = ( workflowRecord . variables as Record < string , unknown > ) || { }
823822
824- let deploymentVersionId : string | undefined
825- /**
826- * Flipped immediately before `executeWorkflowCore` is invoked. While false,
827- * no block has run and no execution effect exists, so a retryable
828- * infrastructure error may be surfaced as a `RetryableSetupError` and the
829- * whole delivery safely re-attempted. Once true, errors are never
830- * reclassified as retryable — retrying after the executor started could
831- * double-run the workflow.
832- */
833- let workflowCoreStarted = false
823+ let deploymentVersionId : string | undefined
824+ /**
825+ * Flipped immediately before `executeWorkflowCore` is invoked. While false,
826+ * no block has run and no execution effect exists, so a retryable
827+ * infrastructure error may be surfaced as a `RetryableSetupError` and the
828+ * whole delivery safely re-attempted. Once true, errors are never
829+ * reclassified as retryable — retrying after the executor started could
830+ * double-run the workflow.
831+ */
832+ let workflowCoreStarted = false
834833
835- try {
834+ try {
835+ return await withResourceOutboundScope ( { workspaceId } , async ( ) => {
836836 const workflowStatePromise = payload . deploymentVersionId
837837 ? loadWorkflowDeploymentVersionState (
838838 payload . workflowId ,
@@ -1175,105 +1175,105 @@ async function executeWebhookJobInternal(
11751175 executedAt : new Date ( ) . toISOString ( ) ,
11761176 provider : payload . provider ,
11771177 }
1178- } catch ( error : unknown ) {
1179- const errorMessage = toError ( error ) . message
1180- const errorStack = error instanceof Error ? error . stack : undefined
1178+ } )
1179+ } catch ( error : unknown ) {
1180+ const errorMessage = toError ( error ) . message
1181+ const errorStack = error instanceof Error ? error . stack : undefined
11811182
1182- /**
1183- * Mirrors the schedule executor's setup boundary: an infrastructure error
1184- * raised before the workflow core started left no execution effect, so it
1185- * is surfaced as a `RetryableSetupError` — releasing the idempotency claim
1186- * and, while attempts remain, requeueing without recording a terminal
1187- * failed row for an attempt that will be retried. Exhausted retries fall
1188- * through to normal failure handling but still throw typed so a provider
1189- * redelivery is not rejected for a run that never happened.
1190- */
1191- const retryableSetupCause =
1192- ! workflowCoreStarted && isRetryableInfrastructureError ( error )
1193- ? describeRetryableInfrastructureError ( error )
1194- : undefined
1195- if ( retryableSetupCause && hasRemainingWebhookInfraRetry ( payload ) ) {
1196- logger . warn ( `[${ requestId } ] Retryable setup failure before webhook workflow started` , {
1197- workflowId : payload . workflowId ,
1198- provider : payload . provider ,
1199- cause : retryableSetupCause ,
1200- } )
1201- throw new RetryableSetupError ( errorMessage , { cause : retryableSetupCause } )
1202- }
1183+ /**
1184+ * Mirrors the schedule executor's setup boundary: an infrastructure error
1185+ * raised before the workflow core started left no execution effect, so it
1186+ * is surfaced as a `RetryableSetupError` — releasing the idempotency claim
1187+ * and, while attempts remain, requeueing without recording a terminal
1188+ * failed row for an attempt that will be retried. Exhausted retries fall
1189+ * through to normal failure handling but still throw typed so a provider
1190+ * redelivery is not rejected for a run that never happened.
1191+ */
1192+ const retryableSetupCause =
1193+ ! workflowCoreStarted && isRetryableInfrastructureError ( error )
1194+ ? describeRetryableInfrastructureError ( error )
1195+ : undefined
1196+ if ( retryableSetupCause && hasRemainingWebhookInfraRetry ( payload ) ) {
1197+ logger . warn ( `[${ requestId } ] Retryable setup failure before webhook workflow started` , {
1198+ workflowId : payload . workflowId ,
1199+ provider : payload . provider ,
1200+ cause : retryableSetupCause ,
1201+ } )
1202+ throw new RetryableSetupError ( errorMessage , { cause : retryableSetupCause } )
1203+ }
12031204
1204- logger . error (
1205- `[${ requestId } ] Webhook execution failed` ,
1206- loggingSession . projectDiagnosticError ( error , {
1207- workflowId : payload . workflowId ,
1208- provider : payload . provider ,
1209- } )
1210- )
1205+ logger . error (
1206+ `[${ requestId } ] Webhook execution failed` ,
1207+ loggingSession . projectDiagnosticError ( error , {
1208+ workflowId : payload . workflowId ,
1209+ provider : payload . provider ,
1210+ } )
1211+ )
12111212
1212- // The finalized flag is set inside a fire-and-forget post-execution promise; await it so the
1213- // signal is reliable and the failure is fully persisted before we decide fault vs error.
1214- await loggingSession . waitForPostExecution ( )
1213+ // The finalized flag is set inside a fire-and-forget post-execution promise; await it so the
1214+ // signal is reliable and the failure is fully persisted before we decide fault vs error.
1215+ await loggingSession . waitForPostExecution ( )
12151216
1216- // A failure inside workflow execution (block error, provider 4xx, missing required field, etc.)
1217- // is finalized by core and already recorded in the execution logs. That is a user/workflow error,
1218- // not a trigger.dev job fault — complete the run normally so we don't fire a false alert. Errors
1219- // that were not finalized came from the webhook pipeline itself, so we re-throw to fault below.
1220- if ( wasExecutionFinalizedByCore ( error , executionId ) ) {
1221- return {
1222- success : false ,
1223- workflowId : payload . workflowId ,
1224- executionId,
1225- output : hasExecutionResult ( error ) ? error . executionResult . output : { } ,
1226- executedAt : new Date ( ) . toISOString ( ) ,
1227- provider : payload . provider ,
1228- }
1217+ // A failure inside workflow execution (block error, provider 4xx, missing required field, etc.)
1218+ // is finalized by core and already recorded in the execution logs. That is a user/workflow error,
1219+ // not a trigger.dev job fault — complete the run normally so we don't fire a false alert. Errors
1220+ // that were not finalized came from the webhook pipeline itself, so we re-throw to fault below.
1221+ if ( wasExecutionFinalizedByCore ( error , executionId ) ) {
1222+ return {
1223+ success : false ,
1224+ workflowId : payload . workflowId ,
1225+ executionId,
1226+ output : hasExecutionResult ( error ) ? error . executionResult . output : { } ,
1227+ executedAt : new Date ( ) . toISOString ( ) ,
1228+ provider : payload . provider ,
12291229 }
1230+ }
12301231
1231- try {
1232- await loggingSession . safeStart ( {
1233- userId : actorUserId ,
1234- actorUserId,
1235- billingAttribution,
1236- workspaceId,
1237- variables : { } ,
1238- triggerData : {
1239- isTest : false ,
1240- correlation,
1241- } ,
1242- deploymentVersionId,
1243- } )
1244-
1245- const executionResult = hasExecutionResult ( error )
1246- ? error . executionResult
1247- : {
1248- success : false ,
1249- output : { } ,
1250- logs : [ ] ,
1251- }
1252- const { traceSpans } = buildTraceSpans ( executionResult )
1232+ try {
1233+ await loggingSession . safeStart ( {
1234+ userId : actorUserId ,
1235+ actorUserId,
1236+ billingAttribution,
1237+ workspaceId,
1238+ variables : { } ,
1239+ triggerData : {
1240+ isTest : false ,
1241+ correlation,
1242+ } ,
1243+ deploymentVersionId,
1244+ } )
12531245
1254- await loggingSession . safeCompleteWithError ( {
1255- endedAt : new Date ( ) . toISOString ( ) ,
1256- totalDurationMs : 0 ,
1257- error : {
1258- message : errorMessage || 'Webhook execution failed' ,
1259- stackTrace : errorStack ,
1260- } ,
1261- traceSpans,
1262- executionState : executionResult . executionState ,
1263- } )
1264- } catch ( loggingError ) {
1265- logger . error (
1266- `[${ requestId } ] Failed to complete logging session` ,
1267- loggingSession . projectDiagnosticError ( loggingError )
1268- )
1269- }
1246+ const executionResult = hasExecutionResult ( error )
1247+ ? error . executionResult
1248+ : {
1249+ success : false ,
1250+ output : { } ,
1251+ logs : [ ] ,
1252+ }
1253+ const { traceSpans } = buildTraceSpans ( executionResult )
1254+
1255+ await loggingSession . safeCompleteWithError ( {
1256+ endedAt : new Date ( ) . toISOString ( ) ,
1257+ totalDurationMs : 0 ,
1258+ error : {
1259+ message : errorMessage || 'Webhook execution failed' ,
1260+ stackTrace : errorStack ,
1261+ } ,
1262+ traceSpans,
1263+ executionState : executionResult . executionState ,
1264+ } )
1265+ } catch ( loggingError ) {
1266+ logger . error (
1267+ `[${ requestId } ] Failed to complete logging session` ,
1268+ loggingSession . projectDiagnosticError ( loggingError )
1269+ )
1270+ }
12701271
1271- if ( retryableSetupCause ) {
1272- throw new RetryableSetupError ( errorMessage , { cause : retryableSetupCause } )
1273- }
1274- throw error
1272+ if ( retryableSetupCause ) {
1273+ throw new RetryableSetupError ( errorMessage , { cause : retryableSetupCause } )
12751274 }
1276- } )
1275+ throw error
1276+ }
12771277}
12781278
12791279export const webhookExecution = task ( {
0 commit comments