cloudflare-workflows

from jezweb/claude-skills

Skills for Claude Code CLI such as full stack dev Cloudflare, React, Tailwind v4, and AI integrations.

213 stars24 forksUpdated Jan 26, 2026
npx skills add https://github.com/jezweb/claude-skills --skill cloudflare-workflows

SKILL.md

Cloudflare Workflows

Status: Production Ready ✅ (GA since April 2025) Last Updated: 2026-01-09 Dependencies: cloudflare-worker-base (for Worker setup) Latest Versions: wrangler@4.58.0, @cloudflare/workers-types@4.20260109.0

Recent Updates (2025):

  • April 2025: Workflows GA release - waitForEvent API, Vitest testing, CPU time metrics, 4,500 concurrent instances
  • October 2025: Instance creation rate 10x faster (100/sec), concurrency increased to 10,000
  • 2025 Limits: Max steps 1,024, state persistence 1MB/step (100MB-1GB per instance), event payloads 1MB, CPU time 5 min max
  • Testing: cloudflare:test module with introspectWorkflowInstance, disableSleeps, mockStepResult, mockEvent modifiers
  • Platform: Waiting instances don't count toward concurrency, retention 3-30 days, subrequests 50-1,000

Quick Start (5 Minutes)

# 1. Scaffold project
npm create cloudflare@latest my-workflow -- --template cloudflare/workflows-starter --git --deploy false
cd my-workflow

# 2. Configure wrangler.jsonc
{
  "name": "my-workflow",
  "main": "src/index.ts",
  "compatibility_date": "2025-11-25",
  "workflows": [{
    "name": "my-workflow",
    "binding": "MY_WORKFLOW",
    "class_name": "MyWorkflow"
  }]
}

# 3. Create workflow (src/index.ts)
import { WorkflowEntrypoint, WorkflowStep, WorkflowEvent } from 'cloudflare:workers';

export class MyWorkflow extends WorkflowEntrypoint<Env, Params> {
  async run(event: WorkflowEvent<Params>, step: WorkflowStep) {
    const result = await step.do('process', async () => { /* work */ });
    await step.sleep('wait', '1 hour');
    await step.do('continue', async () => { /* more work */ });
  }
}

# 4. Deploy and test
npm run deploy
npx wrangler workflows instances list my-workflow

CRITICAL: Extends WorkflowEntrypoint, implements run() with step methods, bindings in wrangler.jsonc


Known Issues Prevention

This skill prevents 12 documented errors with Cloudflare Workflows.

Issue #1: waitForEvent Skips Events After Timeout in Local Dev

Error: Events sent after a waitForEvent() timeout are ignored in subsequent waitForEvent() calls Environment: Local development (wrangler dev) only - works correctly in production Source: GitHub Issue #11740

Why It Happens: Bug in miniflare that was fixed in production (May 2025) but not ported to local emulator. After a timeout, the event queue becomes corrupted for that instance.

Prevention:

  • Test waitForEvent timeout scenarios in production/staging, not local dev
  • Avoid chaining multiple waitForEvent() calls where timeouts are expected

Example of Bug:

export class MyWorkflow extends WorkflowEntrypoint<Env, Params> {
  async run(event: WorkflowEvent<Params>, step: WorkflowStep) {
    for (let i = 0; i < 3; i++) {
      try {
        const evt = await step.waitForEvent(`wait-${i}`, {
          type: 'user-action',
          timeout: '5 seconds'
        });
        console.log(`Iteration ${i}: Received event`);
      } catch {
        console.log(`Iteration ${i}: Timeout`);
      }
    }
  }
}
// In wrangler dev:
// - Iteration 1: ✅ receives event
// - Iteration 2: ⏱️ times out (expected)
// - Iteration 3: ❌ does not receive event (BUG - event is sent but ignored)

Status: Known bug, fix pending for miniflare.


Issue #2: getPlatformProxy() Fails With Workflow Bindings

Error: MiniflareCoreError [ERR_RUNTIME_FAILURE]: The Workers runtime failed to start Message: Worker's binding refers to service with named entrypoint, but service has no such entrypoint Source: GitHub Issue #9402

Why It Happens: getPlatformProxy() from wrangler package doesn't support Workflow bindings (similar to how it handles Durable Objects). This blocks Next.js integration and local CLI scripts.

Prevention:

  • Option 1: Comment out workflow bindings when using getPlatformProxy()
  • Option 2: Create separate wrangler.cli.jsonc without workflows for CLI scripts
  • Option 3: Access workflow bindings directly via deployed worker, not proxy
// Workaround: Separate config for CLI scripts
// wrangler.cli.jsonc (no workflows)
{
  "name": "my-worker",
  "main": "src/index.ts",
  "compatibility_date": "2025-01-20"
  // workflows commented out
}

// Use in script:
import { getPlatformProxy } from 'wrangler';
const { env } = await getPlatformProxy({ configPath: './wrangler.cli.jsonc' });

Status: Known limitation, fix planned (filter workflows similar to DOs).


Issue #3: Workflow Instance Lost After Immediate Redirect (Local Dev)

Error: Instance ID returned but instance.not_found when queried Environment: Local development (wrangler dev) only - works correctly in production Source: [GitHub Issue #10806](https://github.com/cloudflare/work

...

Read full content

Repository Stats

Stars213
Forks24
LicenseMIT License