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
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
(<class 'agentops.exceptions.InvalidApiKeyException'>, <class 'agentops.exceptions.ApiServerException'>)
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:
# 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.
Bug Description
Client.init(api_key="invalid-key")silently succeeds instead of raisingInvalidApiKeyExceptionorApiServerException. 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
Stack Trace
Root Cause
agentops/client/client.py:118-145—_start_auth_task()runs_fetch_auth_async(api_key)in a daemon thread viaasyncio.run(). When_fetch_auth_asyncraisesApiServerException, the exception is caught inside the thread and never propagated back toinit().At line 200,
init()callsself._start_auth_task(self.config.api_key)and immediately proceeds, markingself._initialized = Trueat line 246 regardless of auth outcome.Compare with the working test
test_auth_flowwhich doesn't check for errors — it only verifies the happy path.Impact
init()validates the API keySuggested Fix
Make the first auth attempt synchronous in
init(), then switch to async for token refresh:Found by running the test suite. Happy to submit a PR if confirmed.