AgentOps-AI / AgentOps-AI/agentops
bug: Client.init() silently succeeds with invalid API key — async auth swallows exceptions
- 主要语言
- Python
- 星标
- 5.8k
- 派生
- 619
- PR 合并指标
- 30 天内没有已合并 PR
描述
## Bug Description
`Client.init(api_key="invalid-key")` silently succeeds instead of raising `InvalidApiKeyException` or `ApiServerException`. The async auth refactor moved authentication into a background daemon thread (`_start_auth_task`), so auth errors are swallowed and never propagated to the caller. Users get no feedback when their API key is wrong — they only discover the problem later when span exports silently fail with 401 errors.
## Reproduction
```bash
git clone --depth=1 https://github.com/AgentOps-AI/agentops.git
cd agentops
uv venv .venv && source .venv/bin/activate
uv pip install -e . pytest pytest-asyncio pytest-mock pytest-recording vcrpy requests-mock openai anthropic "openai-agents[voice]"
pytest tests/integration/test_auth_flow.py::test_auth_flow_invalid_key -v --timeout=60 -p no:depends
```
## Stack Trace
```
FAILED tests/integration/test_auth_flow.py::test_auth_flow_invalid_key - Failed: DID NOT RAISE any of
(, )
tests/integration/test_auth_flow.py:49: Failed
with pytest.raises((InvalidApiKeyException, ApiServerException)) as exc_info:
E Failed: DID NOT RAISE any of (...)
```
## Root Cause
`agentops/client/client.py:118-145` — `_start_auth_task()` runs `_fetch_auth_async(api_key)` in a daemon thread via `asyncio.run()`. When `_fetch_auth_async` raises `ApiServerException`, the exception is caught inside the thread and never propagated back to `init()`.
At line 200, `init()` calls `self._start_auth_task(self.config.api_key)` and immediately proceeds, marking `self._initialized = True` at line 246 regardless of auth outcome.
Compare with the working test `test_auth_flow` which doesn't check for errors — it only verifies the happy path.
## Impact
- Users with invalid/expired API keys get silently initialized clients
- No error feedback at init time — auth failures only surface as 401 export errors later
- Breaks the expected contract that `init()` validates the API key
## Suggested Fix
Make the first auth attempt synchronous in `init()`, then switch to async for token refresh:
```python
# In init(), replace _start_auth_task with synchronous first attempt:
if self.config.api_key:
try:
import asyncio
response = asyncio.run(self._fetch_auth_async(self.config.api_key))
if not response:
raise InvalidApiKeyException("Authentication failed")
except ApiServerException:
raise
```
---
Found by running the test suite. Happy to submit a PR if confirmed.
贡献指南
评估
这个 Issue 还没有评估数据。