AgentOps-AI / AgentOps-AI/agentops

bug: Client.init() silently succeeds with invalid API key — async auth swallows exceptions

未关闭
#1,336 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
主要语言
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 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。