webhook-response-not-sent

This error occurs when a webhook is configured with respondWith: "manual" but the workflow does not send a response using request.respondWith() before the webhook execution completes.


Error Message

Workflow run did not send a response

Why This Happens

When you create a webhook with respondWith: "manual", you are responsible for calling request.respondWith() to send the HTTP response back to the caller. If the workflow execution completes without sending a response, this error will be thrown.

The webhook infrastructure waits for a response to be sent, and if none is provided, it cannot complete the HTTP request properly.


Common Causes

Forgetting to Call request.respondWith()

// Error - no response sent export async function webhookWorkflow() {  "use workflow";   const webhook = await createWebhook({  respondWith: "manual",  });   const request = await webhook;  const data = await request.json();   // Process data...  console.log(data);   // Error: workflow ends without calling request.respondWith() }

Solution: Always call request.respondWith() when using manual response mode.

// Fixed - response sent export async function webhookWorkflow() {  "use workflow";   const webhook = await createWebhook({  respondWith: "manual",  });   const request = await webhook;  const data = await request.json();   // Process data...  console.log(data);   // Send response before workflow ends  await request.respondWith(new Response("Processed", { status: 200 }));  }

Conditional Response Logic

// Error - response only sent in some branches export async function webhookWorkflow() {  "use workflow";   const webhook = await createWebhook({  respondWith: "manual",  });   const request = await webhook;  const data = await request.json();   if (data.isValid) {  await request.respondWith(new Response("OK", { status: 200 }));  }  // Error: no response when data.isValid is false }

Solution: Ensure all code paths send a response.

// Fixed - response sent in all branches export async function webhookWorkflow() {  "use workflow";   const webhook = await createWebhook({  respondWith: "manual",  });   const request = await webhook;  const data = await request.json();   if (data.isValid) {   await request.respondWith(new Response("OK", { status: 200 }));   } else {   await request.respondWith(new Response("Invalid data", { status: 400 }));   }  }

Exception Before Response

// Error - exception thrown before response export async function webhookWorkflow() {  "use workflow";   const webhook = await createWebhook({  respondWith: "manual",  });   const request = await webhook;   // Error occurs here  throw new Error("Something went wrong");    // Never reached  await request.respondWith(new Response("OK", { status: 200 })); }

Solution: Use try-catch to handle errors and send appropriate responses.

// Fixed - error handling with response export async function webhookWorkflow() {  "use workflow";   const webhook = await createWebhook({  respondWith: "manual",  });   const request = await webhook;   try {   // Process request...  const result = await processData(request);   await request.respondWith(new Response("OK", { status: 200 }));   } catch (error) {   // Send error response  await request.respondWith(   new Response("Internal error", { status: 500 })   );   }  }

Alternative: Use Default Response Mode

If you don't need custom response control, consider using the default response mode which automatically returns a 202 Accepted response:

// Automatic 202 response - no manual response needed export async function webhookWorkflow() {  "use workflow";   const webhook = await createWebhook();   const request = await webhook;   // Process request asynchronously  await processData(request);   // No need to call request.respondWith() }

Learn More