General
env-var-hygiene - Claude MCP Skill
Environment variable management across Vercel, Convex, and other platforms. Invoke for: trailing whitespace issues, cross-platform parity, Invalid character errors, webhook secrets, API key management, production deployment, dev vs prod configuration.
SEO Guide: Enhance your AI agent with the env-var-hygiene tool. This Model Context Protocol (MCP) server allows Claude Desktop and other LLMs to environment variable management across vercel, convex, and other platforms. invoke for: trailing whi... Download and configure this skill to unlock new capabilities for your AI workflow.
Documentation
SKILL.md# Environment Variable Hygiene
Best practices for managing environment variables across deployment platforms.
## Triggers
Invoke when user mentions:
- "env var", "environment variable", "production deploy"
- "webhook secret", "API key", "token"
- "Invalid character in header", "ERR_INVALID_CHAR"
- "silent failure", "webhook not working"
- "Vercel", "Convex", "deployment", "secrets"
## Core Principles
### 1. Trailing Whitespace Kills
Env vars with `\n` or trailing spaces cause cryptic errors:
- "Invalid character in header content" (HTTP headers)
- Webhook signature mismatch
- Silent authentication failures
**Root Cause:** Copy-paste or `echo` introduces invisible characters.
**Prevention:**
```bash
# ✅ Use printf, not echo
printf '%s' 'sk_live_xxx' | vercel env add STRIPE_SECRET_KEY production
# ✅ Trim when setting
bunx convex env set --prod KEY "$(echo 'value' | tr -d '\n')" # or: npx convex ...
# ❌ Don't use echo directly
echo "sk_live_xxx" | vercel env add KEY production # May add \n
```
### 2. Cross-Platform Parity
Shared tokens (webhook secrets, auth tokens) must be identical across platforms:
- Vercel ↔ Convex
- Frontend ↔ Backend
- Dev ↔ Staging ↔ Prod (within each platform)
**Common Pitfall:** Set token on one platform, forget the other.
**Prevention:**
```bash
# Generate token once
TOKEN=$(openssl rand -hex 32)
# Set on ALL platforms
bunx convex env set --prod CONVEX_WEBHOOK_TOKEN "$(printf '%s' "$TOKEN")" # or: npx convex ...
printf '%s' "$TOKEN" | vercel env add CONVEX_WEBHOOK_TOKEN production
```
### 3. Validate Format Before Use
API keys have specific formats. Validate before deployment:
| Service | Pattern | Example |
|---------|---------|---------|
| Stripe Secret | `sk_(test\|live)_[A-Za-z0-9]+` | `sk_live_xxx` |
| Stripe Public | `pk_(test\|live)_[A-Za-z0-9]+` | `pk_live_xxx` |
| Stripe Webhook | `whsec_[A-Za-z0-9]+` | `whsec_xxx` |
| Stripe Price | `price_[A-Za-z0-9]+` | `price_xxx` |
| Clerk Secret | `sk_(test\|live)_[A-Za-z0-9]+` | `sk_live_xxx` |
### 4. Dev ≠ Prod
Separate deployments have separate env var stores:
- Setting `.env.local` doesn't affect production
- Convex dev and prod are separate deployments
- Vercel has per-environment variables
**Always verify prod separately:**
```bash
# Convex
bunx convex env list --prod # or: npx convex ...
# Vercel
vercel env ls --environment=production
```
### 5. CLI Environment Gotcha
`CONVEX_DEPLOYMENT=prod:xxx npx convex data` may return dev data.
**Always use explicit flags:**
```bash
# ❌ Unreliable
CONVEX_DEPLOYMENT=prod:xxx npx convex data
# ✅ Reliable
bunx convex run --prod module:function # or: npx convex ...
bunx convex env list --prod
```
### 6. Env Load Semantics (Restart Required)
Many runtimes load `.env.local` once at process start.
If code logs "missing X" but `.env.local` has X:
- you edited `.env.local` after server started. Restart dev server.
- your shell env overrides dotenv (incl empty string):
`printenv KEY` then `unset KEY`.
## Quick Reference
### Setting Env Vars Safely
**Convex:**
```bash
# Dev
bunx convex env set KEY "value" # or: npx convex ...
# Prod (use --prod flag)
bunx convex env set --prod KEY "$(printf '%s' 'value')"
```
**Vercel:**
```bash
# Production
printf '%s' 'value' | vercel env add KEY production
# With explicit environment
vercel env add KEY production --force
```
### Checking Env Vars
**Convex:**
```bash
bunx convex env list # dev
bunx convex env list --prod # prod
```
**Vercel:**
```bash
vercel env ls # all
vercel env ls --environment=production # prod only
```
### Detecting Issues
**Trailing whitespace:**
```bash
# Check Convex prod
bunx convex env list --prod | while IFS= read -r line; do
if [[ "$line" =~ [[:space:]]$ ]]; then
echo "WARNING: $(echo "$line" | cut -d= -f1) has trailing whitespace"
fi
done
```
**Format validation:**
```bash
# Validate Stripe key format
value=$(bunx convex env list --prod | grep "^STRIPE_SECRET_KEY=" | cut -d= -f2-)
[[ "$value" =~ ^sk_(test|live)_[A-Za-z0-9]+$ ]] || echo "Invalid format"
```
## References
See `references/` directory:
- `format-patterns.md` - Regex patterns for common services
- `platform-specifics.md` - Vercel, Convex, Railway platform details
- `hygiene-checklist.md` - Pre-deployment validation checklist
- `parity-verification.md` - Cross-platform token verification
## Related Commands
- `/pre-deploy` - Comprehensive pre-deployment checklist
- `/env-parity-check` - Cross-platform token verification
- `/stripe-check` - Stripe-specific environment audit
---
*Based on 2026-01-17 incident: Trailing `\n` in `STRIPE_SECRET_KEY` caused "Invalid character in header" error. Token mismatch between Vercel and Convex caused silent webhook failures.*Signals
Information
- Repository
- phrazzld/claude-config
- Author
- phrazzld
- Last Sync
- 3/2/2026
- Repo Updated
- 3/1/2026
- Created
- 1/18/2026
Reviews (0)
No reviews yet. Be the first to review this skill!
Related Skills
mem0
Integrate Mem0 Platform into AI applications for persistent memory, personalization, and semantic search. Use this skill when the user mentions "mem0", "memory layer", "remember user preferences", "persistent context", "personalization", or needs to add long-term memory to chatbots, agents, or AI apps. Covers Python and TypeScript SDKs, framework integrations (LangChain, CrewAI, Vercel AI SDK, OpenAI Agents SDK, Pipecat), and the full Platform API. Use even when the user doesn't explicitly say "mem0" but describes needing conversation memory, user context retention, or knowledge retrieval across sessions.
upgrade-nodejs
Upgrading Bun's Self-Reported Node.js Version
cursorrules
CrewAI Development Rules
browser-use
Automates browser interactions for web testing, form filling, screenshots, and data extraction. Use when the user needs to navigate websites, interact with web pages, fill forms, take screenshots, or extract information from web pages.
Related Guides
Bear Notes Claude Skill: Your AI-Powered Note-Taking Assistant
Learn how to use the bear-notes Claude skill. Complete guide with installation instructions and examples.
Mastering tmux with Claude: A Complete Guide to the tmux Claude Skill
Learn how to use the tmux Claude skill. Complete guide with installation instructions and examples.
OpenAI Whisper API Claude Skill: Complete Guide to AI-Powered Audio Transcription
Learn how to use the openai-whisper-api Claude skill. Complete guide with installation instructions and examples.