All skills
davila7 avatar

/cloudflare-deploy

@72b6736

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/davila7/claude-code-templates/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 warnings1d4 checks · Risk SAFE
  • Gen Agent Trust Hub1d

    The skill is a comprehensive documentation and reference suite for deploying applications and infrastructure to the Cloudflare platform. It provides detailed technical guidance, code snippets, and architectural patterns for various services including Workers, Pages, D1, R2, and AI Gateway. No malicious patterns, obfuscation, or unauthorized data access were detected.

  • Socket1d

    1 alert: gptAnomaly

  • Snyk1d

    Risk: LOW · No issues

  • Runlayer7mo

    304/310 files flagged

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

Last checked against GitHub 20 hours ago.

Activeupdated 8 months ago
author
openai

README badge

README badge for davila7/claude-code-templates/cloudflare-deploy