Skip to content
Back to skills

1570 Gotchas C82806cd

ASecurity

**Cause:** Worker exceeded CPU time limit (10ms standard, 30ms unbound) **Solution:** Use `ctx.waitUntil()` for background work, offload heavy compute to Durable Objects, or consider Workers AI for ML workloads

  • 9 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 11, 2026
developmenttypescriptgobashnodenodejsexpressapi

Works with

  • api

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 1570-gotchas_c82806cd --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 1570 Gotchas C82806cd?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 1570 Gotchas C82806cd
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-1570-gotchas-c82806cd/badge)](https://www.skillsdirectory.com/skills/tools-only-1570-gotchas-c82806cd)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# Workers Gotchas

## Common Errors

### "Too much CPU time used"

**Cause:** Worker exceeded CPU time limit (10ms standard, 30ms unbound)  
**Solution:** Use `ctx.waitUntil()` for background work, offload heavy compute to Durable Objects, or consider Workers AI for ML workloads

### "Module-Level State Lost"

**Cause:** Workers are stateless between requests; module-level variables reset unpredictably  
**Solution:** Use KV, D1, or Durable Objects for persistent state; don't rely on module-level variables

### "Body has already been used"

**Cause:** Attempting to read response body twice (bodies are streams)  
**Solution:** Clone response before reading: `response.clone()` or read once and create new Response with the text

### "Node.js module not found"

**Cause:** Node.js built-ins not available by default  
**Solution:** Use Workers APIs (e.g., R2 for file storage) or enable Node.js compat with `"compatibility_flags": ["nodejs_compat_v2"]`

### "Cannot fetch in global scope"

**Cause:** Attempting to use fetch during module initialization  
**Solution:** Move fetch calls inside handler functions (fetch, scheduled, etc.) where they're allowed

### "Subrequest depth limit exceeded"

**Cause:** Too many nested subrequests creating deep call chain  
**Solution:** Flatten request chain or use service bindings for direct Worker-to-Worker communication

### "D1 read-after-write inconsistency"

**Cause:** D1 is eventually consistent; reads may not reflect recent writes  
**Solution:** Use D1 Sessions (2024+) to guarantee read-after-write consistency within a session:

```typescript
const session = env.DB.withSession()
await session.prepare('INSERT INTO users (name) VALUES (?)').bind('Alice').run()
const user = await session.prepare('SELECT * FROM users WHERE name = ?').bind('Alice').first() // Guaranteed to see Alice
```

**When to use sessions:** Write → Read patterns, transactions requiring consistency

### "wrangler types not generating TypeScript definitions"

**Cause:** Type generation not configured or outdated  
**Solution:** Run `npx wrangler types` after changing bindings in wrangler.jsonc:

```bash
npx wrangler types  # Generates .wrangler/types/runtime.d.ts
```

Add to `tsconfig.json`: `"include": [".wrangler/types/**/*.ts"]`

Then import: `import type { Env } from './.wrangler/types/runtime';`

### "Durable Object RPC errors with deprecated fetch pattern"

**Cause:** Using old `stub.fetch()` pattern instead of RPC (2024+)  
**Solution:** Export methods directly, call via RPC:

```typescript
// ❌ Old fetch pattern
export class MyDO {
  async fetch(request: Request) {
    const { method } = await request.json()
    if (method === 'increment') return new Response(String(await this.increment()))
  }
  async increment() {
    return ++this.value
  }
}
const stub = env.DO.get(id)
const res = await stub.fetch('http://x', { method: 'POST', body: JSON.stringify({ method: 'increment' }) })

// ✅ RPC pattern (type-safe, no serialization overhead)
export class MyDO {
  async increment() {
    return ++this.value
  }
}
const stub = env.DO.get(id)
const count = await stub.increment() // Direct method call
```

### "WebSocket connection closes unexpectedly"

**Cause:** Worker reaches CPU limit while maintaining WebSocket connection  
**Solution:** Use WebSocket hibernation (2024+) to offload idle connections:

```typescript
export class WebSocketDO {
  async webSocketMessage(ws: WebSocket, message: string) {
    // Handle message
  }
  async webSocketClose(ws: WebSocket, code: number) {
    // Cleanup
  }
}
```

Hibernation automatically suspends inactive connections, wakes on events

### "Framework middleware not working with Workers"

**Cause:** Framework expects Node.js primitives (e.g., Express uses Node streams)  
**Solution:** Use Workers-native frameworks (Hono, itty-router, Worktop) or adapt middleware:

```typescript
// ✅ Hono (Workers-native)
import { Hono } from 'hono'
const app = new Hono()
app.use('*', async (c, next) => {
  /* middleware */ await next()
})
```

See [frameworks.md](./frameworks.md) for full patterns

## Limits

| Limit               | Value     | Notes                         |
| ------------------- | --------- | ----------------------------- |
| Request size        | 100 MB    | Maximum incoming request size |
| Response size       | Unlimited | Supports streaming            |
| CPU time (standard) | 10ms      | Standard Workers              |
| CPU time (unbound)  | 30ms      | Unbound Workers               |
| Subrequests         | 1000      | Per request                   |
| KV reads            | 1000      | Per request                   |
| KV write size       | 25 MB     | Maximum per write             |
| Environment size    | 5 MB      | Total size of env bindings    |

## See Also

- [Patterns](./patterns.md) - Best practices
- [API](./api.md) - Runtime APIs
- [Configuration](./configuration.md) - Setup
- [Frameworks](./frameworks.md) - Hono, routing, validation

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.