사후 분석: 오래된 OAuth와 격리된 크론 작업으로 인한 Claude Max + OpenClaw 청구 오류

자체 호스팅 OpenClaw 설정과 Claude Max가 할당량을 초과하지 않았음에도 billing error — API key has run out of credits를 반환하기 시작했습니다. 이틀간의 디버깅 끝에 두 가지 근본 원인과 고장을 무작위로 보이게 하는 킬 체인이 밝혀졌습니다.
근본 원인 1: 오래된 OAuth 토큰이 전체 제공자를 오염시킴
auth-profiles.json에 두 개의 항목이 있었습니다: 유효한 anthropic:claude-cli OAuth 프로필과 sk-ant-oat01-... 토큰이 있는 anthropic:manual 프로필입니다. 수동 토큰이 만료되었을 때, OpenClaw는 해당 프로필만 실패 처리하지 않고 제공자 수준의 결제 실패로 분류하여 전체 anthropic 제공자를 블랙리스트에 등록하여, 정상 OAuth 프로필을 포함한 모든 모델을 건너뛰었습니다. 로그에는 다음이 표시되었습니다:
reason: "billing" errorPreview: "Provider anthropic has billing issue (skipping all models)" chain_exhausted
유효한 갱신 토큰이 있는 정상 OAuth 프로필은 시도조차 되지 않았습니다.
수정: auth-profiles.json와 openclaw.json에서 anthropic:manual을 완전히 제거합니다. anthropic:claude-cli만 유지합니다.
근본 원인 2: 격리된 cron 작업이 별도의 결제 버킷에 도달함
OpenClaw에는 두 가지 실행 경로가 있습니다:
- 메인 세션 —
/usr/bin/claude바이너리를 실행하며 Max/Pro 구독으로 청구됨 ✅ - 격리/내장 실행 — Anthropic API에 직접 HTTP 요청을 보내며 Extra Usage 버킷으로 청구됨 ❌
sessionTarget: isolated로 설정된 cron 작업은 독립형 내장 에이전트를 실행하며, 이는 CLI가 보내는 Claude Code 헤더 없이 Anthropic API에 직접 HTTP로 호출합니다. Anthropic은 이를 Extra Usage 버킷으로 라우팅하며, 이는 완전히 별도의 할당량입니다. Extra Usage가 꺼져 있으면 모든 격리된 cron 실행은 400을 반환합니다. OpenClaw는 상황을 악화시킵니다: 하나의 결제 오류가 auth-state.json에 disabledUntil을 약 24시간 앞으로 설정하여, 모든 요청(일반 채팅 포함)을 쿨다운이 발생할 때까지 잠급니다. 잠금은 게이트웨이 재시작 후에도 유지됩니다.
전체 킬 체인
- 게이트웨이 재시작 → 놓친 cron 작업이 따라잡기 위해 대기열에 추가됨
- 격리 에이전트가 내장 실행자로 실행 → Anthropic API에 직접 HTTP 호출(CLI 헤더 없음)
- Extra Usage 버킷 → 400 오류
- OpenClaw가 인증 프로필을 약 24시간 동안 잠금 → 모든 요청(일반 채팅 포함) 차단
수정 사항
- 결제 잠금 즉시 해제:
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('해제 완료.') " openclaw gateway restart - 모든 cron 작업을
isolated에서main으로 이동: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'수정 중: {j["name"]}') j['sessionTarget'] = 'main' with open('/home/USER/.openclaw/cron/jobs.json', 'w') as f: json.dump(d, f, indent=2) print('완료.') "
대상: 할당량을 초과하지 않았음에도 무작위 결제 오류가 발생하는 Claude Max 또는 Pro로 OpenClaw를 자체 호스팅하는 모든 사용자.
📖 전체 출처 읽기: r/openclaw
👀 See Also

OpenClaw 프로젝트 운영 체제: 다중 프로젝트 관리 프레임워크
프로젝트를 표준화된 디렉토리로 격리하고, 예측 가능한 작업에는 에이전트 대신 cron을 사용하여 자동화하며, 필수 백업 프로토콜을 구현하여 토큰 사용량을 줄이고 실행 일관성을 향상시키는 프레임워크입니다.

OpenClaw 신뢰성 문제에 대한 실용적인 해결 방법
한 개발자가 OpenClaw 설정을 개선한 8가지 구체적인 기법을 공유했습니다. 여기에는 일일 로그와 지식 그래프를 포함한 3계층 메모리 시스템, 활성화 점수 관리, 파일 기반 규칙 강제 적용 등이 포함됩니다.

Docker/Windows 경험에서 얻은 실용적인 OpenClaw 설정 통찰
한 개발자가 Windows 11/WSL2에서 Docker로 OpenClaw를 실행하며 얻은 구체적인 교훈을 공유합니다. 지속성 문제, Discord 봇 설정, 메모리 관리 접근법, 브라우저 자동화 우회 방법을 다룹니다.

클로드 코드 오케스트레이터가 유용하기 위해 필요한 4가지
Claude Code 오케스트레이터를 구축한 개발자의 실용적인 팁: 미션 문서, 하트비트, 에이전트 간 통신, 감사 가능한 제어.