### Correct Workflow Function Import for start() (TypeScript) Source: https://useworkflow.dev/docs/errors/start-invalid-workflow-function This example shows how to resolve the 'invalid workflow function' error by ensuring the correct workflow function is imported and passed to the `start()` function. Importing a step function instead of the main workflow function can lead to this error. Verify that you are importing the intended workflow. ```typescript import { start } from "workflow/api"; // Error - importing step function instead of workflow import { processStep } from "@/workflows/order"; export async function POST(request: Request) { await start(processStep, ["order-123"]); // Error! return Response.json({ started: true }); } ``` ```typescript import { start } from "workflow/api"; // Fixed - import workflow function import { processOrder } from "@/workflows/order"; export async function POST(request: Request) { await start(processOrder, ["order-123"]); return Response.json({ started: true }); } ``` -------------------------------- ### Valid Webhook Usage: Manual Response Source: https://useworkflow.dev/docs/errors/webhook-invalid-respond-with-value Demonstrates how to use the `respondWith: 'manual'` option to control webhook responses. This example shows how to create a webhook that requires manual response sending and includes processing the request data before sending a custom response. ```typescript // Manual response control const webhook = await createWebhook({ respondWith: "manual", }); const request = await webhook; // Process the request... const data = await request.json(); // Send custom response await request.respondWith( new Response(JSON.stringify({ success: true }), { status: 200, headers: { "Content-Type": "application/json" }, }) ); ``` -------------------------------- ### Webhook Workflow Sending `request.respondWith()` (TypeScript) Source: https://useworkflow.dev/docs/errors/webhook-response-not-sent Provides the corrected version of a webhook workflow that uses `respondWith: "manual"`. This example ensures that `request.respondWith()` is called before the workflow execution ends, resolving the 'Workflow run did not send a response' error. ```typescript 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 // [!code highlight] await request.respondWith(new Response("Processed", { status: 200 })); // [!code highlight] } ``` -------------------------------- ### Avoid Passing Functions in Workflows (TypeScript) Source: https://useworkflow.dev/docs/errors/serialization-failed Demonstrates an error scenario where a function is passed directly to a workflow step, causing a serialization failure. It provides a corrected example showing how to pass configuration data instead and define the function logic within the step. ```typescript // Error - functions cannot be serialized export async function processWorkflow() { "use workflow"; const callback = () => console.log("done"); // [!code highlight] await processStep(callback); // Error! // [!code highlight] } ``` ```typescript // Fixed - pass configuration data instead export async function processWorkflow() { "use workflow"; await processStep({ shouldLog: true }); // [!code highlight] } async function processStep(config: { shouldLog: boolean }) { "use step"; if (config.shouldLog) { // [!code highlight] console.log("done"); // [!code highlight] } // [!code highlight] } ``` -------------------------------- ### Configure Next.js with withWorkflow Wrapper (TypeScript) Source: https://useworkflow.dev/docs/errors/start-invalid-workflow-function This code demonstrates the correct Next.js configuration for integrating with the Workflow DevKit. The error can occur if the `next.config.ts` file is missing the `withWorkflow()` wrapper. Ensure your Next.js configuration is properly enhanced to support workflow functionalities. ```typescript // Error - missing withWorkflow wrapper import type { NextConfig } from "next"; const nextConfig: NextConfig = { // your config }; export default nextConfig; ``` ```typescript // Fixed - includes withWorkflow import { withWorkflow } from "workflow/next"; import type { NextConfig } from "next"; const nextConfig: NextConfig = { // your config }; export default withWorkflow(nextConfig); ``` -------------------------------- ### Direct API Calls with workflow fetch (TypeScript) Source: https://useworkflow.dev/docs/errors/fetch-in-workflow Demonstrates how to use the fetch step function directly from the 'workflow' package to make custom HTTP requests within a workflow function. This is useful for interacting with external APIs. ```typescript import { fetch } from "workflow"; export async function dataWorkflow() { "use workflow"; // Use fetch directly for HTTP requests const response = await fetch("https://api.example.com/data"); // [!code highlight] const data = await response.json(); return data; } ``` -------------------------------- ### Create Hook with Auto-Generated Token (TypeScript) Source: https://useworkflow.dev/docs/errors/hook-conflict Demonstrates the recommended approach of letting the Workflow runtime automatically generate a unique token for a hook. This ensures uniqueness and avoids conflicts. ```typescript export async function processPayment() { "use workflow"; const hook = createHook(); // Auto-generated unique token console.log(`Send webhook to token: ${hook.token}`); const payment = await hook; } ``` -------------------------------- ### Reading File in Workflow (After) Source: https://useworkflow.dev/docs/errors/node-js-module-in-workflow Shows the correct way to handle Node.js module usage by calling a step function from the workflow. Step functions provide full Node.js runtime access, resolving the determinism issue. ```typescript import * as fs from "fs"; export async function processFileWorkflow(filePath: string) { "use workflow"; // Call step function that has Node.js access const content = await read(filePath); // [!code highlight] return content; } async function read(filePath: string) { "use step"; // Node.js modules are allowed in step functions return fs.readFileSync(filePath, "utf-8"); // [!code highlight] } ``` -------------------------------- ### Handle Hook Token Conflict in TypeScript Source: https://useworkflow.dev/docs/errors/hook-conflict Demonstrates how to catch and handle a 'hook-conflict' error when awaiting a hook. This is useful for detecting and managing duplicate processing attempts. ```typescript import { WorkflowRuntimeError } from "@workflow/errors"; export async function processPayment(orderId: string) { "use workflow"; const hook = createHook({ token: `payment-${orderId}` }); try { const payment = await hook; return { success: true, payment }; } catch (error) { if (error instanceof WorkflowRuntimeError && error.slug === "hook-conflict") { // Another workflow is already processing this order return { success: false, reason: "duplicate-processing" }; } throw error; // Re-throw other errors } } ``` -------------------------------- ### Create Hook with Unique Token (TypeScript) Source: https://useworkflow.dev/docs/errors/hook-conflict Shows how to create a hook with a unique token by including a unique identifier, such as an order ID. This prevents conflicts when multiple workflow runs might use the same base token. ```typescript export async function processPayment(orderId: string) { "use workflow"; // Include unique identifier in token const hook = createHook({ token: `payment-${orderId}` }); const payment = await hook; } ``` -------------------------------- ### Reading File in Workflow (Before) Source: https://useworkflow.dev/docs/errors/node-js-module-in-workflow Demonstrates an incorrect approach where a Node.js core module ('fs') is used directly within a workflow function, leading to an error. This highlights the limitation of workflow environments. ```typescript import * as fs from "fs"; export async function processFileWorkflow(filePath: string) { "use workflow"; // This will cause an error - Node.js module in workflow context const content = fs.readFileSync(filePath, "utf-8"); // [!code highlight] return content; } ``` -------------------------------- ### Avoid Passing Class Instances in Workflows (TypeScript) Source: https://useworkflow.dev/docs/errors/serialization-failed Illustrates the issue of passing class instances between workflow boundaries, leading to serialization errors because methods are lost. The solution involves passing plain objects and reconstructing the class within the target step. ```typescript class User { constructor(public name: string) {} greet() { return `Hello ${this.name}` } } // Error - class instances lose methods after serialization export async function greetWorkflow() { "use workflow"; await greetStep(new User("Alice")); // Error! // [!code highlight] } ``` ```typescript class User { constructor(public name: string) {} greet() { return `Hello ${this.name}` } } // Fixed - pass plain object, reconstruct in step export async function greetWorkflow() { "use workflow"; await greetStep({ name: "Alice" }); // [!code highlight] } async function greetStep(userData: { name: string }) { "use step"; const user = new User(userData.name); // [!code highlight] console.log(user.greet()); } ``` -------------------------------- ### Replace setTimeout with sleep in Workflow Source: https://useworkflow.dev/docs/errors/timeout-in-workflow Demonstrates how to replace the unsupported setTimeout function with the workflow-compatible sleep function for introducing delays in workflow execution. The sleep function is tracked in the event log for correct replay. ```typescript import { sleep } from 'workflow'; export async function delayedWorkflow() { "use workflow"; // sleep is tracked in the event log and replays correctly await sleep('5s'); return 'done'; } ``` -------------------------------- ### Valid Webhook Usage: Default Behavior Source: https://useworkflow.dev/docs/errors/webhook-invalid-respond-with-value Shows the default behavior of `createWebhook` when no `respondWith` option is provided. In this case, the webhook automatically returns a `202 Accepted` response, and no manual response sending is required. ```typescript // Returns 202 Accepted automatically const webhook = await createWebhook(); const request = await webhook; // No need to send a response ``` -------------------------------- ### Valid Webhook Usage: Pre-defined Response Source: https://useworkflow.dev/docs/errors/webhook-invalid-respond-with-value Illustrates how to use a pre-defined `Response` object with the `respondWith` option in `createWebhook`. This allows the webhook to send an immediate response without further action within the workflow. ```typescript // Immediate response const webhook = await createWebhook({ respondWith: new Response("Request received", { status: 200 }), }); const request = await webhook; // Response already sent ``` -------------------------------- ### Webhook Workflow with Automatic Response (TypeScript) Source: https://useworkflow.dev/docs/errors/webhook-response-not-sent Demonstrates the alternative to manual response handling in webhooks. By omitting the `respondWith: "manual"` option, the webhook automatically returns a `202 Accepted` response, eliminating the need to call `request.respondWith()` and preventing the 'Workflow run did not send a response' error. ```typescript // Automatic 202 response - no manual response needed export async function webhookWorkflow() { "use workflow"; const webhook = await createWebhook(); // [!code highlight] const request = await webhook; // Process request asynchronously await processData(request); // No need to call request.respondWith() } ``` -------------------------------- ### Webhook Workflow Missing `request.respondWith()` Call (TypeScript) Source: https://useworkflow.dev/docs/errors/webhook-response-not-sent Demonstrates an error scenario where a webhook workflow using `respondWith: "manual"` completes without calling `request.respondWith()`. This leads to the 'Workflow run did not send a response' error because the webhook infrastructure expects a manual response. ```typescript 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() // [!code highlight] } ``` -------------------------------- ### Fix Invalid String in respondWith Source: https://useworkflow.dev/docs/errors/webhook-invalid-respond-with-value Demonstrates how to fix an invalid string value for the `respondWith` option in `createWebhook`. The original code used an incorrect string, while the corrected version uses 'manual' and shows how to send a custom response. ```typescript // Error - invalid string value export async function webhookWorkflow() { "use workflow"; const webhook = await createWebhook({ respondWith: "automatic", // Error! // [!code highlight] }); } ``` ```typescript // Fixed - use "manual" export async function webhookWorkflow() { "use workflow"; const webhook = await createWebhook({ respondWith: "manual", // [!code highlight] }); const request = await webhook; // Send custom response await request.respondWith(new Response("OK", { status: 200 })); // [!code highlight] } ``` -------------------------------- ### Fix fetch Error: Assign workflow fetch to globalThis.fetch (TypeScript) Source: https://useworkflow.dev/docs/errors/fetch-in-workflow Resolves the 'Global "fetch" is unavailable' error by importing the fetch step function from the 'workflow' package and assigning it to globalThis.fetch. This makes HTTP requests available within workflow functions, including those used by libraries like the AI SDK. ```typescript import { generateText } from "ai"; import { openai } from "@ai-sdk/openai"; import { fetch } from "workflow"; // [!code highlight] export async function chatWorkflow(prompt: string) { "use workflow"; globalThis.fetch = fetch; // [!code highlight] // Now generateText() can make HTTP requests via the fetch step const result = await generateText({ model: openai("gpt-4"), prompt, }); return result.text; } ``` ```typescript import { generateText, streamText } from "ai"; import { openai } from "@ai-sdk/openai"; import { fetch } from "workflow"; // [!code highlight] export async function aiWorkflow(userMessage: string) { "use workflow"; globalThis.fetch = fetch; // [!code highlight] // generateText makes HTTP requests to OpenAI const response = await generateText({ model: openai("gpt-4"), prompt: userMessage, }); return response.text; } ``` -------------------------------- ### Fix Non-Response Object in respondWith Source: https://useworkflow.dev/docs/errors/webhook-invalid-respond-with-value Illustrates how to correct an error where a plain object was used instead of a `Response` object for the `respondWith` option. The solution involves using the `Response` constructor to create a valid response object. ```typescript // Error - plain object instead of Response export async function webhookWorkflow() { "use workflow"; const webhook = await createWebhook({ respondWith: { status: 200, body: "OK" }, // Error! // [!code highlight] }); } ``` ```typescript // Fixed - use Response constructor export async function webhookWorkflow() { "use workflow"; const webhook = await createWebhook({ respondWith: new Response("OK", { status: 200 }), // [!code highlight] }); } ``` -------------------------------- ### Polling with Delays in Workflow Source: https://useworkflow.dev/docs/errors/timeout-in-workflow Illustrates how to implement polling logic within a workflow function using the sleep function for delays between checks. This pattern is useful for periodically querying an external service until a condition is met. ```typescript import { sleep } from 'workflow'; export async function pollingWorkflow() { "use workflow"; let status = 'pending'; while (status === 'pending') { status = await checkStatus(); // step function if (status === 'pending') { await sleep('10s'); } } return status; } async function checkStatus() { "use step"; const response = await fetch('https://api.example.com/status'); const data = await response.json(); return data.status; } ``` -------------------------------- ### Hook Token Conflict - Hardcoded Token (TypeScript) Source: https://useworkflow.dev/docs/errors/hook-conflict Illustrates an error scenario where multiple concurrent workflow runs using the same hardcoded hook token will conflict. This highlights the problem that the solutions aim to address. ```typescript // Error - multiple concurrent runs will conflict export async function processPayment() { "use workflow"; const hook = createHook({ token: "payment-hook" }); // [!code highlight] // If another run is already waiting on "payment-hook", this will fail const payment = await hook; } ``` -------------------------------- ### Error Handling with Response in Webhook (TypeScript) Source: https://useworkflow.dev/docs/errors/webhook-response-not-sent Provides a robust solution for handling exceptions in webhook workflows configured with manual responses. This code uses a try-catch block to ensure that `request.respondWith()` is called, sending either a success or an error response, thus preventing the 'Workflow run did not send a response' error. ```typescript export async function webhookWorkflow() { "use workflow"; const webhook = await createWebhook({ respondWith: "manual", }); const request = await webhook; try { // [!code highlight] // Process request... const result = await processData(request); // [!code highlight] await request.respondWith(new Response("OK", { status: 200 })); // [!code highlight] } catch (error) { // [!code highlight] // Send error response // [!code highlight] await request.respondWith( // [!code highlight] new Response("Internal error", { status: 500 }) // [!code highlight] ); // [!code highlight] } // [!code highlight] } ``` -------------------------------- ### Exception Before Response in Webhook Error (TypeScript) Source: https://useworkflow.dev/docs/errors/webhook-response-not-sent Shows an error scenario where an exception is thrown within the webhook workflow before `request.respondWith()` can be called. This prevents the response from being sent, triggering the 'Workflow run did not send a response' error. ```typescript export async function webhookWorkflow() { "use workflow"; const webhook = await createWebhook({ respondWith: "manual", }); const request = await webhook; // Error occurs here // [!code highlight] throw new Error("Something went wrong"); // [!code highlight] // Never reached await request.respondWith(new Response("OK", { status: 200 })); } ``` -------------------------------- ### Scheduled Delays in Workflow Source: https://useworkflow.dev/docs/errors/timeout-in-workflow Shows how to use the sleep function to introduce scheduled delays within a workflow, such as waiting for a specific duration before sending a reminder. This ensures the delay is correctly handled during workflow replay. ```typescript import { sleep } from 'workflow'; export async function reminderWorkflow(message: string) { "use workflow"; // Wait 24 hours before sending reminder await sleep('24h'); await sendReminder(message); return 'reminder sent'; } async function sendReminder(message: string) { "use step"; // Send reminder logic } ``` -------------------------------- ### Add 'use workflow' Directive to Workflow Function (TypeScript) Source: https://useworkflow.dev/docs/errors/start-invalid-workflow-function This snippet demonstrates how to fix the 'invalid workflow function' error by adding the required 'use workflow' directive to a TypeScript workflow function. This directive is essential for the Workflow DevKit to recognize and process the function correctly. Ensure the function is also exported from its file. ```typescript // Error - missing directive export async function processOrder(orderId: string) { // workflow logic return { status: "completed" }; } ``` ```typescript // Fixed - includes directive export async function processOrder(orderId: string) { "use workflow"; // workflow logic return { status: "completed" }; } ``` -------------------------------- ### Conditional Response Logic Error in Webhook (TypeScript) Source: https://useworkflow.dev/docs/errors/webhook-response-not-sent Illustrates a common cause of the 'Workflow run did not send a response' error: conditional logic where `request.respondWith()` is only called in certain branches. If the condition is not met, no response is sent, leading to the error. ```typescript 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 // [!code highlight] } ``` -------------------------------- ### Fixed Conditional Response Logic in Webhook (TypeScript) Source: https://useworkflow.dev/docs/errors/webhook-response-not-sent Presents the solution to the conditional response logic error in webhooks. This corrected code ensures that `request.respondWith()` is called in all possible code paths, guaranteeing a response is always sent, even when data is invalid. ```typescript export async function webhookWorkflow() { "use workflow"; const webhook = await createWebhook({ respondWith: "manual", }); const request = await webhook; const data = await request.json(); if (data.isValid) { // [!code highlight] await request.respondWith(new Response("OK", { status: 200 })); // [!code highlight] } else { // [!code highlight] await request.respondWith(new Response("Invalid data", { status: 400 })); // [!code highlight] } // [!code highlight] } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.