Skip to content

v0.6.41: webhooks fix, workers removal#4154

Merged
waleedlatif1 merged 1 commit intomainfrom
staging
Apr 14, 2026
Merged

v0.6.41: webhooks fix, workers removal#4154
waleedlatif1 merged 1 commit intomainfrom
staging

Conversation

@waleedlatif1
Copy link
Copy Markdown
Collaborator

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Apr 14, 2026 3:44pm

Request Review

@waleedlatif1 waleedlatif1 changed the title v0.6.41: webhooks fix v0.6.41: webhooks fix, workers removal Apr 14, 2026
@waleedlatif1 waleedlatif1 marked this pull request as ready for review April 14, 2026 15:44
@cursor
Copy link
Copy Markdown

cursor bot commented Apr 14, 2026

PR Summary

Medium Risk
Changes webhook execution behavior by removing the shouldExecuteInline() gate for inline-queued jobs, which could impact throughput/latency and error handling for live webhook processing.

Overview
Fixes a regression where non-polling webhook jobs enqueued to the inline backend were not actually executed when shouldExecuteInline() was false.

queueWebhookExecution and processPolledWebhookEvent now always startJob/executeWebhookJob/completeJob in a fire-and-forget task after enqueueing to the inline queue, while still marking the job failed (and logging) on execution errors.

Reviewed by Cursor Bugbot for commit a51333a. Configure here.

@waleedlatif1 waleedlatif1 merged commit 3838b6e into main Apr 14, 2026
20 checks passed
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 14, 2026

Greptile Summary

This PR fixes a regression where non-polling webhook executions (Slack, GitHub, Stripe, and other push-based providers) were silently dropped after BullMQ was removed. The fix splits the execution path by provider type: polling providers (Gmail, Outlook, IMAP, RSS) continue to use the Trigger.dev job queue when that backend is configured, while non-polling providers are now explicitly routed to the inline fire-and-forget path in both queueWebhookExecution and processPolledWebhookEvent.

Confidence Score: 4/5

  • The fix correctly addresses the silent-drop regression; both remaining comments are P2 and do not block merge, but the admission-gate timing warrants a look before this pattern spreads further.
  • No new P0/P1 defects introduced. The admission ticket being released before inline execution completes is technically a P2 (pre-existing design that is now applied to more paths), and the duplicated IIFE block is a maintenance concern. Both are minor enough that the fix is safe to ship.
  • apps/sim/lib/webhooks/processor.ts — review the admission gate release order in processPolledWebhookEvent for the inline path.

Important Files Changed

Filename Overview
apps/sim/lib/webhooks/processor.ts Adds a isPolling && !shouldExecuteInline() branch so polling providers still use the job queue while non-polling providers execute inline via a void IIFE; same pattern duplicated in both queueWebhookExecution and processPolledWebhookEvent.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Webhook HTTP Request] --> B[queueWebhookExecution]
    B --> C{isPollingWebhookProvider?}
    C -- "Yes (gmail/outlook/imap/rss)" --> D{shouldExecuteInline?}
    D -- "false (trigger.dev enabled)" --> E[getJobQueue → trigger.dev enqueue]
    D -- "true (db backend)" --> F[getInlineJobQueue → DB enqueue]
    F --> G[void IIFE: startJob → executeWebhookJob → completeJob]
    C -- "No (slack/stripe/github/etc.)" --> F

    H[processPolledWebhookEvent] --> I[tryAdmit]
    I -- "rejected" --> J[429 at capacity]
    I -- "admitted" --> K[checkWebhookPreprocessing]
    K --> L{isPollingProvider AND not inline?}
    L -- "Yes (trigger.dev)" --> M[getJobQueue → trigger.dev enqueue]
    L -- "No (db backend)" --> N[getInlineJobQueue → DB enqueue]
    N --> O[void IIFE: executeWebhookJob]
    O -.->|ticket already released| P[finally: ticket.release]
    M --> P

    style G fill:#f9f,stroke:#333
    style O fill:#f9f,stroke:#333
    style E fill:#bbf,stroke:#333
    style M fill:#bbf,stroke:#333
Loading

Comments Outside Diff (2)

  1. apps/sim/lib/webhooks/processor.ts, line 580-617 (link)

    P2 Duplicated inline-execution block

    The enqueue-then-fire-IIFE pattern (lines 580–617 here and lines 769–804 in processPolledWebhookEvent) is identical. If either copy needs to change — e.g., to add waitUntil, retry logic, or a different error metric — the other is easy to forget. Extracting this into a shared helper (e.g., executeWebhookJobInline(jobQueue, jobId, payload, requestId)) would keep both call sites in sync.

    // Suggested helper
    async function executeWebhookJobInline(
      jobQueue: JobQueueBackend,
      jobId: string,
      payload: WebhookExecutionPayload,
      requestId: string
    ): Promise<void> {
      void (async () => {
        try {
          await jobQueue.startJob(jobId)
          const output = await executeWebhookJob(payload)
          await jobQueue.completeJob(jobId, output)
        } catch (error) {
          const errorMessage = error instanceof Error ? error.message : String(error)
          logger.error(`[${requestId}] Webhook execution failed`, { jobId, error: errorMessage })
          try {
            await jobQueue.markJobFailed(jobId, errorMessage)
          } catch (markFailedError) {
            logger.error(`[${requestId}] Failed to mark job as failed`, {
              jobId,
              error: markFailedError instanceof Error ? markFailedError.message : String(markFailedError),
            })
          }
        }
      })()
    }

    Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

  2. apps/sim/lib/webhooks/processor.ts, line 757-806 (link)

    P2 Admission ticket released before inline execution completes

    ticket.release() fires in the finally block before the async IIFE finishes. When the inline path runs (database backend or any non-polling provider), the admission gate slot is freed while the workflow execution is still in flight. A burst of polling events can therefore accumulate more concurrent executions than tryAdmit was meant to allow.

    For the Trigger.dev path this is fine — the execution is offloaded externally and the ticket only needs to cover enqueuing. For the inline path, consider holding the ticket until the execution resolves, or documenting that the gate controls enqueue concurrency only.

Reviews (1): Last reviewed commit: "fix(webhooks): non-polling webhook execu..." | Re-trigger Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant