Back to skills
SKILL.md
1570 Gotchas Ee3830f9
ASecurity**Problem:** "stream already consumed" or worker hangs
- 9 stars
- 0 votes
- 0 copies
- 0 views
- Added October 11, 2026
Works with
Security analysis
100/100npx -y skills add tools-only/X-Skills --skill 1570-gotchas_ee3830f9 --agent claude-codeAre you the author of 1570 Gotchas Ee3830f9?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/tools-only-1570-gotchas-ee3830f9)# Gotchas & Troubleshooting
## Critical Pitfalls
### Stream Consumption (MOST COMMON)
**Problem:** "stream already consumed" or worker hangs
**Cause:** `message.raw` is `ReadableStream` - consume once only
**Solution:**
```typescript
// ❌ WRONG
const email1 = await parser.parse(await message.raw.arrayBuffer())
const email2 = await parser.parse(await message.raw.arrayBuffer()) // FAILS
// ✅ CORRECT
const raw = await message.raw.arrayBuffer()
const email = await parser.parse(raw)
```
Consume `message.raw` immediately before any async operations.
### Destination Verification
**Problem:** Emails not forwarding
**Cause:** Destination unverified
**Solution:** Add destination, check inbox for verification email, click link. Verify status: `GET /zones/{id}/email/routing/addresses`
### Mail Authentication
**Problem:** Legitimate emails rejected
**Cause:** Missing SPF/DKIM/DMARC on sender domain
**Solution:** Configure sender DNS:
```dns
example.com. IN TXT "v=spf1 include:_spf.example.com ~all"
selector._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=..."
_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine"
```
### Envelope vs Header
**Problem:** Filtering on wrong address
**Solution:**
```typescript
// Routing/auth: envelope
if (message.from === 'trusted@example.com') {
}
// Display: headers
const display = message.headers.get('from')
```
### SendEmail Limits
| Issue | Limit | Solution |
| ----------- | ------------- | ------------------------ |
| From domain | Must own | Use Email Routing domain |
| Volume | ~100/min Free | Upgrade or throttle |
| Attachments | Not supported | Link to R2 |
| Type | Transactional | No bulk |
## Common Errors
### CPU Time Exceeded
**Cause:** Heavy parsing, large emails
**Solution:**
```typescript
const size = parseInt(message.headers.get('content-length') || '0') / 1024 / 1024
if (size > 20) {
message.setReject('Too large')
return
}
ctx.waitUntil(expensiveWork())
await message.forward('dest@example.com')
```
### Rule Not Triggering
**Causes:** Priority conflict, matcher error, catch-all override
**Solution:** Check priority (lower=first), verify exact match, confirm destination verified
### Undefined Property
**Cause:** Missing header
**Solution:**
```typescript
// ❌ WRONG
const subj = message.headers.get('subject').toLowerCase()
// ✅ CORRECT
const subj = message.headers.get('subject')?.toLowerCase() || ''
```
## Limits
| Resource | Free | Paid |
| ------------ | -------- | ------ |
| Email size | 25 MB | 25 MB |
| Rules | 200 | 200 |
| Destinations | 200 | 200 |
| CPU time | 10ms | 50ms |
| SendEmail | ~100/min | Higher |
## Debugging
### Local
```bash
npx wrangler dev
curl -X POST 'http://localhost:8787/__email' \
--header 'content-type: message/rfc822' \
--data 'From: test@example.com
To: you@yourdomain.com
Subject: Test
Body'
```
### Production
```bash
npx wrangler tail
```
### Pattern
```typescript
export default {
async email(message, env, ctx) {
try {
console.log('From:', message.from)
await process(message, env)
} catch (err) {
console.error(err)
message.setReject(err.message)
}
},
} satisfies ExportedHandler
```
## Auth Troubleshooting
### Check Status
```typescript
const auth = message.headers.get('authentication-results') || ''
console.log({
spf: auth.includes('spf=pass'),
dkim: auth.includes('dkim=pass'),
dmarc: auth.includes('dmarc=pass'),
})
if (!auth.includes('pass')) {
message.setReject('Failed auth')
return
}
```
### SPF Issues
**Causes:** Forwarding breaks SPF, too many lookups (>10), missing includes
**Solution:**
```dns
; ✅ Good
example.com. IN TXT "v=spf1 include:_spf.google.com ~all"
; ❌ Bad - too many
example.com. IN TXT "v=spf1 include:a.com include:b.com ... ~all"
```
### DMARC Alignment
**Cause:** From domain must match SPF/DKIM domain
## Best Practices
1. Consume `message.raw` immediately
2. Verify destinations
3. Handle missing headers (`?.`)
4. Use envelope for routing
5. Check spam scores
6. Test locally first
7. Use `ctx.waitUntil` for background work
8. Size-check early
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.