Claude-skill-registry env-var-hygiene

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.

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/env-var-hygiene" ~/.claude/skills/majiayu000-claude-skill-registry-env-var-hygiene && rm -rf "$T"
manifest: skills/data/env-var-hygiene/SKILL.md
source content

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:

# ✅ Use printf, not echo
printf '%s' 'sk_live_xxx' | vercel env add STRIPE_SECRET_KEY production

# ✅ Trim when setting
npx convex env set --prod KEY "$(echo 'value' | tr -d '\n')"

# ❌ 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:

# Generate token once
TOKEN=$(openssl rand -hex 32)

# Set on ALL platforms
npx convex env set --prod CONVEX_WEBHOOK_TOKEN "$(printf '%s' "$TOKEN")"
printf '%s' "$TOKEN" | vercel env add CONVEX_WEBHOOK_TOKEN production

3. Validate Format Before Use

API keys have specific formats. Validate before deployment:

ServicePatternExample
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:

# Convex
npx convex env list --prod

# 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:

# ❌ Unreliable
CONVEX_DEPLOYMENT=prod:xxx npx convex data

# ✅ Reliable
npx convex run --prod module:function
npx convex env list --prod

Quick Reference

Setting Env Vars Safely

Convex:

# Dev
npx convex env set KEY "value"

# Prod (use --prod flag)
npx convex env set --prod KEY "$(printf '%s' 'value')"

Vercel:

# Production
printf '%s' 'value' | vercel env add KEY production

# With explicit environment
vercel env add KEY production --force

Checking Env Vars

Convex:

npx convex env list           # dev
npx convex env list --prod    # prod

Vercel:

vercel env ls                              # all
vercel env ls --environment=production     # prod only

Detecting Issues

Trailing whitespace:

# Check Convex prod
npx 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:

# Validate Stripe key format
value=$(npx 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.