Post-Mortem: Claude Max + OpenClaw Billing Errors from Stale OAuth and Isolated Cron Jobs

A self-hosted OpenClaw setup with Claude Max started returning billing error — API key has run out of credits despite being well under quota. Two days of debugging revealed two root causes and a kill chain that makes the failure appear random.
Root Cause 1: Stale OAuth Token Poisons Whole Provider
The auth-profiles.json had two entries: a valid anthropic:claude-cli OAuth profile and an anthropic:manual profile with an sk-ant-oat01-... token. When the manual token expired, OpenClaw didn't just fail that profile — it classified it as a provider-level billing failure and blacklisted the entire anthropic provider, skipping every model including the healthy OAuth profile. Logs showed:
reason: "billing" errorPreview: "Provider anthropic has billing issue (skipping all models)" chain_exhausted
The healthy OAuth profile with a valid refresh token was never tried.
Fix: Remove anthropic:manual entirely from auth-profiles.json and openclaw.json. Keep only anthropic:claude-cli.
Root Cause 2: Isolated Cron Jobs Hit a Separate Billing Bucket
OpenClaw has two execution paths:
- Main sessions — runs
/usr/bin/claudebinary, billed to Max/Pro subscription ✅ - Isolated/embedded runs — direct HTTP to Anthropic API, billed to Extra Usage bucket ❌
Cron jobs with sessionTarget: isolated spin up a standalone embedded agent that calls the Anthropic API directly via HTTP — without the Claude Code headers the CLI sends. Anthropic routes it to the Extra Usage bucket, a completely separate quota. With Extra Usage off, every isolated cron run returns a 400. OpenClaw then worsens it: one billing error sets disabledUntil ~24 hours forward in auth-state.json, locking out all requests — including normal chat — until cooldown fires. The lockout survives gateway restarts.
The Full Kill Chain
- Gateway restart → missed cron job queues for catch-up
- Isolated agent fires via embedded runner → direct HTTP call to Anthropic API (no CLI headers)
- Extra Usage bucket → 400 error
- OpenClaw locks auth profile for ~24h → all requests blocked including normal chat
Fixes
- Clear the billing lockout immediately:
python3 -c " import json with open('/home/USER/.openclaw/agents/main/agent/auth-state.json') as f: d = json.load(f) if 'usageStats' in d: for profile in d['usageStats']: d['usageStats'][profile].pop('disabledUntil', None) d['usageStats'][profile].pop('failureCounts', None) d['usageStats'][profile].pop('errorCount', None) d['usageStats'][profile].pop('disabledReason', None) d['usageStats'][profile].pop('lastFailureAt', None) with open('/home/USER/.openclaw/agents/main/agent/auth-state.json', 'w') as f: json.dump(d, f, indent=2) print('Cleared.') " openclaw gateway restart - Move all cron jobs from
isolatedtomain:python3 -c " import json with open('/home/USER/.openclaw/cron/jobs.json') as f: d = json.load(f) jobs = d if isinstance(d, list) else d.get('jobs', []) for j in jobs: if j.get('sessionTarget') == 'isolated': print(f'Fixing: {j["name"]}') j['sessionTarget'] = 'main' with open('/home/USER/.openclaw/cron/jobs.json', 'w') as f: json.dump(d, f, indent=2) print('Done.') "
Who it's for: Anyone self-hosting OpenClaw with Claude Max or Pro who sees random billing errors despite being under quota.
📖 Read the full source: r/openclaw
👀 See Also

OpenClaw setup checklist: six critical steps for new users
A Reddit post outlines six essential configuration steps for OpenClaw users: change default model from Opus to Sonnet to reduce costs, lock gateway host to 127.0.0.1 for security, create SOUL.md for agent personality, avoid installing skills initially, don't create multiple agents, and use /new command to manage conversation context.

CLAUDE.md Files Are Often Organized for Developers, Not AI Models – Here's Why That Matters
CLAUDE.md files commonly place Hard Rules at line 47, after background and tech stack. By the time the model reads constraints, it has already constructed conflicting assumptions. A better structure puts hard rules first.

Custom Command Center App for OpenClaw: React PWA with WebSocket Proxy and Tailscale
A developer built a React PWA command center for their OpenClaw setup, featuring a live agent dashboard, trading desk, and push notifications, using a WebSocket proxy pattern to bridge OpenClaw's loopback-only gateway with devices on a Tailscale mesh.

OpenClaw 4.1 with Gemma 4 Stack: Hybrid Architecture and Setup Fixes
A Reddit post details an optimized local agent stack combining OpenClaw 4.1 with Google's Gemma 4 model, featuring a hybrid architecture, specific configuration fixes for Ollama tool calling, and context window adjustments.