Cloudflare Workflows for durable long-running execution. Use for multi-step workflows, retries, state persistence, or encountering NonRetryableError, execution failed errors.
npx skills add https://github.com/secondsky/claude-skills --skill cloudflare-workflows
Status: Production Ready ✅ | Last Verified: 2025-12-27 | Version: 3.0.0
Dependencies: cloudflare-worker-base (for Worker setup)
Contents: Quick Start • Commands • Agents • Core Concepts • Critical Rules • Top Errors • Common Patterns • When to Load References • Limits
Use the Cloudflare Workflows starter template:
npm create cloudflare@latest my-workflow -- --template cloudflare/workflows-starter --git --deploy false
cd my-workflow
What you get:
src/index.ts:
import { WorkflowEntrypoint, WorkflowStep, WorkflowEvent } from 'cloudflare:workers';
type Env = {
MY_WORKFLOW: Workflow;
};
type Params = {
userId: string;
email: string;
};
export class MyWorkflow extends WorkflowEntrypoint<Env, Params> {
async run(event: WorkflowEvent<Params>, step: WorkflowStep) {
const { userId, email } = event.payload;
// Step 1: Do work with automatic retries
const result = await step.do('process user', async () => {
return { processed: true, userId };
});
// Step 2: Wait before next step
await step.sleep('wait 1 hour', '1 hour');
// Step 3: Continue workflow
await step.do('send email', async () => {
return { sent: true, email };
});
return { completed: true, userId };
}
}
// Worker to trigger workflow
export default {
async fetch(req: Request, env: Env): Promise<Response> {
const instance = await env.MY_WORKFLOW.create({
params: { userId: '123', email: '[email protected]' }
});
return Response.json({
id: instance.id,
status: await instance.status()
});
}
};
Template: See templates/basic-workflow.ts for complete example
{
"name": "my-workflow",
"main": "src/index.ts",
"compatibility_date": "2025-10-22",
"workflows": [
{
"binding": "MY_WORKFLOW",
"name": "my-workflow",
"class_name": "MyWorkflow"
}
]
}
Template: See templates/wrangler-workflows-config.jsonc
npm run deploy
Interactive slash commands for workflow development:
| Command | Description | Use When |
|---------|-------------|----------|
| /workflow-setup | Complete wizard for new workflow projects | Starting new project, need full setup |
| /workflow-create | Quick scaffolding for workflow classes | Adding workflow to existing project |
| /workflow-debug | Interactive debugging with error patterns | Troubleshooting workflow issues |
| /workflow-test | Test workflows locally and remotely | Validating workflow behavior |
Example Usage:
/workflow-setup # Full guided setup wizard
/workflow-create # Quick workflow scaffolding
/workflow-debug # Debug workflow issues
/workflow-test # Test workflow execution
Autonomous agents for complex workflow tasks:
| Agent | Description | Triggers |
|-------|-------------|----------|
| workflow-debugger | Auto-detects and fixes configuration/runtime errors | "debug workflow", "fix workflow errors" |
| workflow-optimizer | Analyzes performance, cost, and reliability | "optimize workflow", "improve performance" |
| workflow-setup-assistant | Autonomous project scaffolding | "setup workflow", "create first workflow" |
Key Capabilities:
Automation scripts in scripts/ directory:
| Script | Purpose |
|--------|---------|
| validate-workflow-config.sh | Validate wrangler.jsonc configuration |
| test-workflow.sh | Create and test workflow instances |
| benchmark-workflow.sh | Measure performance and cost |
| generate-workflow.sh | Scaffold new workflows from templates |
| check-workflow-limits.sh | Validate against Cloudflare limits |
Usage:
./scripts/validate-workflow-config.sh # Check config
./scripts/test-workflow.sh my-workflow # Test workflow
./scripts/benchmark-workflow.sh my-workflow 10 # Benchmark 10 runs
./scripts/generate-workflow.sh MyWorkflow # Generate scaffold
./scripts/check-workflow-limits.sh src/workflows/my-workflow.ts
Every workflow must extend WorkflowEntrypoint:
export class MyWorkflow extends WorkflowEntrypoint<Env, Params> {
async run(event: WorkflowEvent<Params>, step: WorkflowStep) {
// Workflow logic here
}
}
Key Points:
Env: Environment bindings (KV, D1, etc.)Params: Typed payload passed when creating workflow instanceevent: Contains id, payload, timestampstep: Methods for durable executionAll workflow work MUST be done in steps for durability:
// step.do - Execute work with automatic retries
await step.do('step name', async () => {
return { result: 'data' };
});
// step.sleep - Wait for duration
await step.sleep('wait', '1 hour');
// step.sleepUntil - Wait until timestamp
await step.sleepUntil('wait until', Date.now() + 3600000);
// step.waitForEvent - Wait for external event
const event = await step.waitForEvent('payment received', 'payment.completed', {
timeout: '30 minutes'
});
CRITICAL: All I/O (fetch, KV, D1, R2) must happen inside step.do() callbacks!
Reference: See references/workflow-patterns.md for all patterns
✅ Perform all I/O inside step.do() - Required for durability
✅ Use named steps - Makes debugging easier
✅ Return JSON-serializable data from steps - Required for state persistence
✅ Use step.sleep() for delays - Don't use setTimeout()
✅ Handle errors explicitly - Use try/catch in step callbacks
✅ Use NonRetryableError for permanent failures - Stops retries
Workflow Patterns: See references/workflow-patterns.md for:
❌ Never do I/O outside step.do() - Will fail with "I/O context" error
❌ Never use setTimeout() or setInterval() - Use step.sleep() instead
❌ Never return non-serializable data - Functions, Promises, etc. will fail
❌ Never hardcode timeouts - Use workflow config
❌ Never ignore NonRetryableError - Indicates permanent failure
Error:
Cannot perform I/O on behalf of a different request
Cause: Performing I/O outside step.do() callback
Solution:
// ❌ WRONG
const data = await fetch('https://api.example.com');
await step.do('use data', async () => {
return data; // Error!
});
// ✅ CORRECT
const data = await step.do('fetch data', async () => {
const response = await fetch('https://api.example.com');
return await response.json();
});
Error:
Cannot serialize workflow state
Cause: Returning non-JSON-serializable data from step
Solution:
// ❌ WRONG
await step.do('process', async () => {
return { fn: () => {} }; // Functions not serializable
});
// ✅ CORRECT
await step.do('process', async () => {
return { result: 'data' }; // JSON-serializable
});
Error: Workflow retries forever on permanent failures
Solution:
import { NonRetryableError } from 'cloudflare:workers';
await step.do('validate', async () => {
if (!isValid) {
throw new NonRetryableError('Invalid input'); // Stop retries
}
return { valid: true };
});
Error:
WorkflowEvent 'payment.completed' not found
Cause: Event name mismatch between waitForEvent and trigger
Solution:
// Workflow waits for event
const event = await step.waitForEvent('wait payment', 'payment.completed', {
timeout: '30 minutes'
});
// Trigger event with EXACT same name
await instance.trigger('payment.completed', { amount: 100 });
Error:
Workflow execution failed: Step timeout exceeded
Cause: Step exceeds maximum CPU time (30 seconds)
Solution:
// ❌ WRONG
await step.do('long task', async () => {
for (let i = 0; i < 1000000; i++) {
// Long computation
}
});
// ✅ CORRECT - Break into smaller steps
for (let i = 0; i < 100; i++) {
await step.do(`batch ${i}`, async () => {
// Process batch
});
}
All Issues: See references/common-issues.md for complete documentation
Basic workflow with steps executing in order. Each step completes before the next begins.
Use cases: Order processing, user onboarding, data pipelines
Load templates/basic-workflow.ts for complete example
Workflow with time delays between steps using step.sleep() or step.sleepUntil().
Use cases: Reminder sequences, scheduled tasks, delayed notifications
Load templates/scheduled-workflow.ts for complete example
Wait for external events with step.waitForEvent(). Always set timeout and handle with NonRetryableError:
const payment = await step.waitForEvent('wait payment', 'payment.completed', {
timeout: '30 minutes'
});
if (!payment) throw new NonRetryableError('Payment timeout');
Load templates/workflow-with-events.ts for complete example
Use NonRetryableError for permanent failures (404), regular Error for transient failures (5xx):
const data = await step.do('fetch', async () => {
const response = await fetch(url);
if (!response.ok) {
if (response.status === 404) throw new NonRetryableError('Not found');
throw new Error('Temporary failure'); // Will retry
}
return await response.json();
});
Load templates/workflow-with-retries.ts for complete example with retry configuration
From Worker: Create instances via env.MY_WORKFLOW.create(), get status with instance.status(), trigger events with instance.trigger().
From Cron: Use scheduled() handler to create workflow instances on schedule.
Load templates/worker-trigger.ts for complete Worker trigger example
Load templates/scheduled-workflow.ts for complete Cron trigger example
references/common-issues.md: Encountering I/O context, serialization, NonRetryableError, event naming, or timeout errors; troubleshooting workflow failures.
references/workflow-patterns.md: Building complex orchestration, approval workflows, idempotency patterns, or circuit breaker patterns.
references/wrangler-commands.md: Need CLI commands for managing workflow instances, debugging stuck workflows, or monitoring production.
references/production-checklist.md: Preparing for deployment, need pre-deployment verification, setting up monitoring/error handling.
references/limits-quotas.md: Hitting instance/step/payload limits, optimizing for cost, designing high-volume workflows.
references/2025-features.md: Using events system, enhanced retries, instance lifecycle control, or latest Workflows features.
references/metrics-analytics.md: Setting up monitoring, custom metrics, external logging integration, or workflow dashboards.
references/troubleshooting.md: Complex debugging scenarios, stuck instances, systematic diagnosis, performance issues.
templates/: basic-workflow.ts (sequential), scheduled-workflow.ts (delays/sleep), workflow-with-events.ts (waitForEvent), workflow-with-retries.ts (custom retry), worker-trigger.ts (Worker triggers), wrangler-workflows-config.jsonc (Wrangler config), parallel-execution-workflow.ts (batched parallel processing), circuit-breaker-workflow.ts (resilient external calls)
Key Commands: wrangler workflows create, wrangler workflows instances list/describe/terminate, wrangler deploy
Load references/wrangler-commands.md for complete CLI reference with all workflow management commands, monitoring workflows, and debugging stuck instances.
Workflows automatically persist state between steps. No manual state management needed:
export class StatefulWorkflow extends WorkflowEntrypoint {
async run(event, step) {
// Step 1 result is automatically persisted
const result1 = await step.do('step 1', async () => {
return { data: 'value' };
});
// Even if workflow crashes here, step 1 won't re-run
await step.sleep('wait', '1 hour');
// Step 2 can use step 1's result (still available after sleep)
await step.do('step 2', async () => {
console.log(result1.data); // 'value' - persisted!
});
}
}
Key Points:
| Resource | Limit |
|----------|-------|
| Step CPU Time | 30 seconds |
| Workflow Duration | 30 days |
| Step Payload Size | 128 KB |
| Workflow Payload Size | 128 KB |
| Steps per Workflow | 1,000 |
| Concurrent Instances | 1,000 per workflow |
| Event Payload Size | 128 KB |
Workarounds:
Example Cost (1M workflow runs):
Solution: Move all I/O into step.do() callbacks → See references/common-issues.md #1
Solution: Return only JSON-serializable data from steps → See references/common-issues.md #2
Solution: Throw NonRetryableError for permanent failures → See references/common-issues.md #3
Solution: Ensure event names match exactly → See references/common-issues.md #4
Solution: Break long computations into smaller steps → See references/common-issues.md #5
10-Point Pre-Deployment Checklist: I/O context isolation, JSON serialization, NonRetryableError usage, event name consistency, step duration limits, error handling, retry configuration, timeouts, workflow naming, and monitoring.
Load references/production-checklist.md for complete checklist with detailed explanations, code examples, verification steps, and deployment workflow.
Workflows: https://developers.cloudflare.com/workflows/ • API Reference: https://developers.cloudflare.com/workflows/reference/ • Examples: https://developers.cloudflare.com/workflows/examples/ • Blog: https://blog.cloudflare.com/cloudflare-workflows/
Assess Kubernetes workloads and cluster configuration for AKS Automatic compatibility. Identifies incompatibilities, generates fixes, and guides migration from AKS Standard to AKS Automatic. WHEN: migrate to AKS Automatic, check AKS Automatic readiness, validate manifests for Automatic, assess cluster for Automatic compatibility, fix deployment for Automatic compatibility, identify AKS Automatic migration blockers, is my cluster ready for AKS Automatic.
Discovers available Azure OpenAI model capacity across regions and projects. Analyzes quota limits, compares availability, and recommends optimal deployment locations based on capacity requirements. USE FOR: find capacity, check quota, where can I deploy, capacity discovery, best region for capacity, multi-project capacity search, quota analysis, model availability, region comparison, check TPM availability. DO NOT USE FOR: actual deployment (hand off to preset or customize after discovery), quota increase requests (direct user to Azure Portal), listing existing deployments.
Interactive guided deployment flow for Azure OpenAI models with full customization control. Step-by-step selection of model version, SKU (GlobalStandard/Standard/ProvisionedManaged), capacity, RAI policy (content filter), and advanced options (dynamic quota, priority processing, spillover). USE FOR: custom deployment, customize model deployment, choose version, select SKU, set capacity, configure content filter, RAI policy, deployment options, detailed deployment, advanced deployment, PTU deployment, provisioned throughput. DO NOT USE FOR: quick deployment to optimal region (use preset).
Unified Azure OpenAI model deployment skill with intelligent intent-based routing. Handles quick preset deployments, fully customized deployments (version/SKU/capacity/RAI policy), and capacity discovery across regions and projects. USE FOR: deploy model, deploy gpt, create deployment, model deployment, deploy openai model, set up model, provision model, find capacity, check model availability, where can I deploy, best region for model, capacity analysis. DO NOT USE FOR: listing existing deployments (use foundry_models_deployments_list MCP tool), deleting deployments, agent creation (use agent/create), project creation (use project/create).
Intelligently deploys Azure OpenAI models to optimal regions by analyzing capacity across all available regions. Automatically checks current region first and shows alternatives if needed. USE FOR: quick deployment, optimal region, best region, automatic region selection, fast setup, multi-region capacity check, high availability deployment, deploy to best location. DO NOT USE FOR: custom SKU selection (use customize), specific version selection (use customize), custom capacity configuration (use customize), PTU deployments (use customize).
This skill should be used when working with LaminDB, an open-source data framework for biology that makes data queryable, traceable, reproducible, and FAIR. Use when managing biological datasets (scRNA-seq, spatial, flow cytometry, etc.), tracking computational workflows, curating and validating data with biological ontologies, building data lakehouses, or ensuring data lineage and reproducibility in biological research. Covers data management, annotation, ontologies (genes, cell types, diseases, tissues), schema validation, integrations with workflow managers (Nextflow, Snakemake) and MLOps platforms (W&B, MLflow), and deployment strategies.
Latch platform for bioinformatics workflows. Build pipelines with Latch SDK, @workflow/@task decorators, deploy serverless workflows, LatchFile/LatchDir, Nextflow/Snakemake integration.
Run Python code in the cloud with serverless containers, GPUs, and autoscaling. Use when deploying ML models, running batch processing jobs, scheduling compute-intensive tasks, or serving APIs that require GPU acceleration or dynamic scaling.
Take secondsky/cloudflare-workflows from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.