All skills
openai avatar

/cloudflare-deploy

@bf9e226 official
by openaiopenai/skills28k stars
1,891

Deploy applications and infrastructure to Cloudflare using Workers, Pages, and related platform services. Use when the user asks to deploy, host, publish, or set up a project on Cloudflare.

Use this Skill: https://skilld.dev/gh/openai/skills/cloudflare-deploy

This session only. Nothing lands on disk.

referencescron-triggersgotchas.md

≈1.6k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Cron Triggers Gotchas

Common Errors

"Timezone Issues"

Problem: Cron runs at wrong time relative to local timezone
Cause: All crons execute in UTC, no local timezone support
Solution: Convert local time to UTC manually

Conversion formula: utcHour = (localHour - utcOffset + 24) % 24

Examples:

  • 9am PST (UTC-8) → (9 - (-8) + 24) % 24 = 17 → 0 17 * * *
  • 2am EST (UTC-5) → (2 - (-5) + 24) % 24 = 7 → 0 7 * * *
  • 6pm JST (UTC+9) → (18 - 9 + 24) % 24 = 33 % 24 = 9 → 0 9 * * *

Daylight Saving Time: Adjust manually when DST changes, or schedule at times unaffected by DST (e.g., 2am-4am local time usually safe)

"Cron Not Executing"

Cause: Missing scheduled() export, invalid syntax, propagation delay (<15min), or plan limits
Solution: Verify export exists, validate at crontab.guru, wait 15+ min after deploy, check plan limits

"Duplicate Executions"

Cause: At-least-once delivery
Solution: Track execution IDs in KV - see idempotency pattern below

"Execution Failures"

Cause: CPU exceeded, unhandled exceptions, network timeouts, binding errors
Solution: Use try-catch, AbortController timeouts, ctx.waitUntil() for long ops, or Workflows for heavy tasks

"Local Testing Not Working"

Problem: /__scheduled endpoint returns 404 or doesn't trigger handler
Cause: Missing scheduled() export, wrangler not running, or incorrect endpoint format
Solution:

  1. Verify scheduled() is exported:
export default {
  async scheduled(controller, env, ctx) {
    console.log("Cron triggered");
  },
};
  1. Start dev server:
npx wrangler dev
  1. Use correct endpoint format (URL-encode spaces as +):
# Correct
curl "http://localhost:8787/__scheduled?cron=*/5+*+*+*+*"

# Wrong (will fail)
curl "http://localhost:8787/__scheduled?cron=*/5 * * * *"
  1. Update Wrangler if outdated:
npm install -g wrangler@latest

"waitUntil() Tasks Not Completing"

Problem: Background tasks in ctx.waitUntil() fail silently or don't execute
Cause: Promises rejected without error handling, or handler returns before promise settles
Solution: Always await or handle errors in waitUntil promises:

export default {
  async scheduled(controller, env, ctx) {
    // BAD: Silent failures
    ctx.waitUntil(riskyOperation());
    
    // GOOD: Explicit error handling
    ctx.waitUntil(
      riskyOperation().catch(err => {
        console.error("Background task failed:", err);
        return logError(err, env);
      })
    );
  },
};

"Idempotency Issues"

Problem: At-least-once delivery causes duplicate side effects (double charges, duplicate emails)
Cause: No deduplication mechanism
Solution: Use KV to track execution IDs:

export default {
  async scheduled(controller, env, ctx) {
    const executionId = `${controller.cron}-${controller.scheduledTime}`;
    const existing = await env.EXECUTIONS.get(executionId);
    
    if (existing) {
      console.log("Already executed, skipping");
      controller.noRetry();
      return;
    }
    
    await env.EXECUTIONS.put(executionId, "1", { expirationTtl: 86400 }); // 24h TTL
    await performIdempotentOperation(env);
  },
};

"Security Concerns"

Problem: __scheduled endpoint exposed in production allows unauthorized cron triggering
Cause: Testing endpoint available in deployed Workers
Solution: Block __scheduled in production:

export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);
    
    // Block __scheduled in production
    if (url.pathname === "/__scheduled" && env.ENVIRONMENT === "production") {
      return new Response("Not Found", { status: 404 });
    }
    
    return handleRequest(request, env, ctx);
  },
  
  async scheduled(controller, env, ctx) {
    // Your cron logic
  },
};

Also: Use env.API_KEY for secrets (never hardcode)

Alternative: Add middleware to verify request origin:

export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);
    
    if (url.pathname === "/__scheduled") {
      // Check Cloudflare headers to verify internal request
      const cfRay = request.headers.get("cf-ray");
      if (!cfRay && env.ENVIRONMENT === "production") {
        return new Response("Not Found", { status: 404 });
      }
    }
    
    return handleRequest(request, env, ctx);
  },
  
  async scheduled(controller, env, ctx) {
    // Your cron logic
  },
};

Limits & Quotas

Limit Free Paid Notes
Triggers per Worker 3 Unlimited Maximum cron schedules per Worker
CPU time 10ms 50ms May need ctx.waitUntil() or Workflows
Execution guarantee At-least-once At-least-once Duplicates possible - use idempotency
Propagation delay Up to 15 minutes Up to 15 minutes Time for changes to take effect globally
Min interval 1 minute 1 minute Cannot schedule more frequently
Cron accuracy ±1 minute ±1 minute Execution may drift slightly

Testing Best Practices

Unit tests:

  • Mock ScheduledController, ExecutionContext, and bindings
  • Test each cron expression separately
  • Verify noRetry() is called when expected
  • Use Vitest with @cloudflare/vitest-pool-workers for realistic env

Integration tests:

  • Test via /__scheduled endpoint in dev environment
  • Verify idempotency logic with duplicate scheduledTime values
  • Test error handling and retry behavior

Production: Start with long intervals (*/30 * * * *), monitor Cron Events for 24h, set up alerts before reducing interval

Resources

Source: SKILL.md on GitHub

2 warnings17d5 checks · Risk SAFE
  • Gen Agent Trust Hub17d

    This skill provides comprehensive guidance for deploying and managing infrastructure on the Cloudflare platform. It includes extensive educational material on secure development practices, such as preventing SQL injection and managing secrets effectively. No malicious patterns or security risks were identified.

  • Socket17d

    2 alerts: gptAnomaly

  • Snyk17d

    Risk: LOW · No issues

  • Runlayer7mo

    310/310 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at bf9e226. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Activeupdated 8 months ago

README badge

README badge for openai/skills/cloudflare-deploy

Deploys applications and infrastructure to Cloudflare's platform, including Workers, Pages, D1, R2, Durable Objects, KV, and other services. Use decision trees to route to the right Cloudflare product based on compute, storage, AI, networking, security, or media needs.

Generated from the current SKILL.md.

Does this skill cover all Cloudflare products?
The skill is a consolidated index covering compute, storage, AI, networking, security, media, and developer tools on Cloudflare. It uses decision trees to route you to the right product reference, then loads detailed guidance for that product.
What authentication is required before deploying?
Run `npx wrangler whoami` to check if authenticated. For local deployment, use `wrangler login` (one-time OAuth). For CI/CD, set the `CLOUDFLARE_API_TOKEN` environment variable.
What should I do if deployment fails due to network issues?
Rerun the deploy with `sandbox_permissions=require_escalated` to grant elevated network access, which is required for outbound requests to Cloudflare during deployment.
How long does a Cloudflare deployment typically take?
Deployments may take several minutes. Use appropriate timeout values in your configuration or CI/CD environment.

Generated from the current SKILL.md. These answers refresh after source changes.