Workflow not resuming upon receiving webhook or finishing sleep()
@pranaygp is already working on this.
Since Jan 27, 2026.
- Dominant language
- TypeScript
- Stars
- 2.4k
- Forks
- 365
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 169
Description
I'm using a webhook loop plus sleep (in case webhooks are misfired/missed) with an update step in order to perform long-running requests on fal.ai:
async function runFalJobWithWebhook<Id extends EndpointType>(
endpoint: Id,
{
input,
priority = "normal",
onEnqueue,
onQueueUpdate,
}: {
input: InputType<Id>
priority?: QueuePriority
onEnqueue?: (requestId: string) => Promise<void>
onQueueUpdate?: (status: QueueStatus) => Promise<void>
}
): Promise<Result<OutputType<Id>>> {
const workflowCtx = getWorkflowMetadata()
const parentId = workflowCtx.workflowRunId || null
const webhook = createWebhook()
const job = await queueFalJobStep(endpoint, {
input,
webhookUrl: webhook.url,
parentId,
priority,
})
const initialResult = await updateFalJobStep(endpoint, job.external_job_id!)
if (initialResult) {
return initialResult as Result<OutputType<Id>>
}
while (true) {
const request = await Promise.race([
webhook,
sleep("1 minute").then(() => null),
])
if (request) {
const falWebhookObject = await request.json()
const falId: string = falWebhookObject.request_id
if (falId !== job.external_job_id) {
console.error(
`Received webhook for unknown fal ID ${falId}, expected ${job.external_job_id}`
)
}
}
const result = await updateFalJobStep(endpoint, job.external_job_id!)
if (result) {
await falCompletedMarkerStep(endpoint, job.external_job_id!)
return result as Result<OutputType<Id>>
}
}
throw new FatalError("Workflow terminated without receiving job result")
}
This isn't working specifically on Vercel.
As you can see, the webhook fires, but the workflow isn't resuming.
Same with the sleep function. Just a single iteration and it doesn't resume after.
This isn't consistent either. I've seen times when sleep does continue and the entire thing finishes.
Even more concerningly, sometimes this function seems to return the object returned by await falCompletedMarkerStep(endpoint, job.external_job_id!), which isn't the value that's supposed to be returned.
I know this has happened based on errors returned by callers of this function upon receiving this unexpected object. It is really absurd, not sure how that would happen.
What is going on? Is this a bug? Am I doing this incorrectly?
To add some context: the reason why there's two webhooks waiting at the same time, is that I run this runFalJobWithWebhook twice concurrently, using Promise.allSettled(), from the workflow.
Version: "workflow": "^4.0.1-beta.18"
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.