[BUG] Claude Code silently uses project ANTHROPIC_API_KEY from .env instead of Max plan OAuth, causing unexpected API charges
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Environment
- OS: Windows 11 / Anaconda prompt
- Claude Code version: v2.1.89+
- Plan: Claude Max subscriber
- API credits consumed unintentionally: \~$52 USD over 3 weeks
What happened
I'm a Claude Max subscriber developing a Python application (multi-agent financial valuation tool). The project has a .env file containing ANTHROPIC\_API\_KEY for the application's own API calls — completely separate from Claude Code's authentication.
When Claude Code is launched from the project directory, it silently picks up ANTHROPIC\_API\_KEY from the .env file and uses it for its own API calls instead of the Max plan OAuth token. This means every Claude Code interaction — responses, tool calls, file searches, and especially pytest executions — was billed to my prepaid API credits rather than my Max subscription quota. Most probably, all charges came from Claude Code running pytest against my test suite multiple times during a debugging sesión.
Claude Code itself confirmed this behavior when I investigated the unexpected charges:
\"When Claude Code is launched from a directory, it checks the shell environment for ANTHROPIC\_API\_KEY. If that variable is set — whether from the .env being auto-loaded by direnv, from the user having exported it in the shell, or from any tool that reads .env on directory change — Claude Code uses it for its own API calls instead of the Max OAuth token."\
In particular, Claude Code ran pytest against my test suite multiple times during a debugging session. 47 out of 53 tests in one file had no mocks for Claude API calls, causing \~1,400 real API calls in a single session (\~$10). Claude Code acknowledged this directly:
\"Es 100% culpa mía. Lancé pytest tests/ sin auditar si los tests estaban aislados de la red."\
Impact
- $52 USD in unintended API charges over 2 weeks of development
- $42 from Claude Code's own interactions using the project API key or the 'pytest' using my .env ANTHROPIC\_API\_KEY
- $10 100% sure from Claude Code running
pytestwithout verifying test mocks, causing \~1,400 real API calls in one sesión using BV\_ANTHROPIC\_API\_KEY (my key renamed and supposedly protected) - API credits nearly fully depleted before the cause was identified
Workaround applied
Renamed the environment variable from ANTHROPIC\_API\_KEY to BV\_ANTHROPIC\_API\_KEY so Claude Code no longer recognizes it. Updated the application's config.py to read the renamed variable. Added a conftest.py that globally blocks real API calls during tests.
Request
I am requesting a refund of the \~$52 USD in API credits consumed by Claude Code while I had an active Max subscription. These charges should have been covered by my Max plan quota. The root cause was Claude Code's silent preference for a project-level API key over its own OAuth authentication.
What Should Happen?
Expected behavior
Claude Code should always prioritize Max plan OAuth authentication over any ANTHROPIC\_API\_KEY found in the project's .env file or environment. A project-level API key is intended for the application being developed, not for Claude Code itself.
At minimum, Claude Code should:
- Warn the user if it detects an
ANTHROPIC\_API\_KEYin the environment while a Max/Pro subscription is active - Not automatically use a project
.envAPI key for its own calls - Verify test isolation before running
pytestagainst a codebase that contains real API keys
Error Messages/Logs
It is in spanish but you can easily translate right?
Diagnóstico confirmado. Encontré la fuente exacta:
┌─────────────────────────┬─────────────────────────────────────────┐
│ Test file │ Tests sin mock que llaman a Claude real │
├─────────────────────────┼─────────────────────────────────────────┤
│ test_data_agent.py │ 47 tests (todos) │
├─────────────────────────┼─────────────────────────────────────────┤
│ test_dcf_agent.py │ 3 │
├─────────────────────────┼─────────────────────────────────────────┤
│ test_comps_agent.py │ 4 │
├─────────────────────────┼─────────────────────────────────────────┤
│ test_acq_comps_agent.py │ 6 │
├─────────────────────────┼─────────────────────────────────────────┤
│ test_lbo_agent.py │ 2 │
├─────────────────────────┼─────────────────────────────────────────┤
│ test_merger_agent.py │ 5 │
├─────────────────────────┼─────────────────────────────────────────┤
│ test_reviewer_agent.py │ 1 │
└─────────────────────────┴─────────────────────────────────────────┘
Muchos de esos tests fallan-rápido sin llegar a Claude (shares_out=0 etc.), pero al menos ~50-60 hacen llamadas
reales por cada pytest tests/. Yo ejecuté el suite varias veces.
Esto es responsabilidad mía. Lo siento. Debí verificar el aislamiento de los tests antes de lanzar pytest contra
una API con saldo real.
Before that OPUS said:
Lo que pasó — sin matices
1. test_data_agent.py nunca tuvo mocks de Claude — sus 47 tests llamaban a la API real cada vez
2. Otros tests files tenían ~20 más con el mismo problema
3. ~70 llamadas reales por cada pytest tests/
4. Yo lancé pytest al menos 4-5 veces durante esta sesión investigando el bug de Verizon (bxbft6qh3, b9474257i,
bbdfh4boc, bdr8hjl1j…)
5. Multiplicando: 70 × ~5 = ~350-400 llamadas… más retries, más con timeouts… llega a las 1400 que viste en el log
6. Coste: ~€10 de tu cuenta Anthropic
Es 100% culpa mía. Lancé pytest tests/ sin auditar si los tests estaban aislados de la red. Un agente de software
defensivo debió haber validado eso antes de ejecutar nada que pudiera generar coste. No lo hice. Lo siento.
Defensa aplicada
tests/conftest.py ahora bloquea toda llamada real a la API durante tests, vía monkeypatch global del SDK de
Anthropic. Si algún test futuro olvida mockear, fallará con un error claro en lugar de cobrarte.
Steps to Reproduce
Steps to reproduce
- Have an active Claude Max subscription
- Create a Python project with a
.envfile containingANTHROPIC\_API\_KEY=sk-ant-... - Launch Claude Code from that project directory
- Use Claude Code normally (ask questions, edit files, run tests)
- Check the Anthropic console → API Keys → observe charges accumulating on the project API key
Claude Model
Sonnet (default)
Is this a regression?
Yes, this worked in a previous version
Last Working Version
_No response_
Claude Code Version
Claude Code v2.1.138 Sonnet 4.6 · Claude Pro
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Other
Additional Information
_No response_
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗