You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
bug: Client.init() silently succeeds with invalid API key — async auth swallows exceptions #1336
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.
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:ifself.config.api_key:
try:
importasyncioresponse=asyncio.run(self._fetch_auth_async(self.config.api_key))
ifnotresponse:
raiseInvalidApiKeyException("Authentication failed")
exceptApiServerException:
raise
Found by running the test suite. Happy to submit a PR if confirmed.
Silent success on an invalid API key is a particularly dangerous failure mode for agentic deployments — the agent initializes, runs sessions, and silently drops all telemetry. Operators only discover the problem when they notice the dashboard is empty, which in a long-running autonomous agent might be hours or days later.
The root cause you identified (auth in a daemon thread with swallowed exceptions) is a common async initialization anti-pattern. Two fixes worth combining:
1. Synchronous auth probe before returning from init(). A lightweight synchronous preflight request (even just a token validation endpoint) at init time guarantees the key is valid before the call returns. The daemon thread can still handle refresh and rotation; the synchronous probe just confirms the initial credential is valid.
2. Identity invalidation event on deferred auth failure. If the daemon thread auth does fail after init returns (e.g., token revoked mid-session), the SDK should emit an identity invalidation event that upstream agents and orchestrators can intercept. An agent that loses its identity silently mid-session is a trust boundary violation — downstream tools and collaborating agents may have made decisions based on the assumption the agent was authenticated.
From a behavioral trust perspective, an agent that initializes with an invalid API key and then silently fails to report telemetry has a broken attestation chain — its actions cannot be attributed or audited. AgentFolio and SATP track observable telemetry as a trust signal; silent initialization failure creates a gap in that record that looks identical to an agent that simply had no activity.
I reproduced this on main with the reported test (tests/integration/test_auth_flow.py::test_auth_flow_invalid_key): init() returned successfully and the ApiServerException never reached the caller.
The fix keeps the background task for async callers, but when init() runs without a running event loop (the synchronous API), it now authenticates before returning and lets InvalidApiKeyException / ApiServerException propagate. Other unexpected errors are still swallowed as before, and the happy path is unchanged.
Both tests in tests/integration/test_auth_flow.py pass locally. Opening a PR that links this issue.
Activity
0xbrainkid commentedon Apr 15, 2026
Silent success on an invalid API key is a particularly dangerous failure mode for agentic deployments — the agent initializes, runs sessions, and silently drops all telemetry. Operators only discover the problem when they notice the dashboard is empty, which in a long-running autonomous agent might be hours or days later.
The root cause you identified (auth in a daemon thread with swallowed exceptions) is a common async initialization anti-pattern. Two fixes worth combining:
1. Synchronous auth probe before returning from
init(). A lightweight synchronous preflight request (even just a token validation endpoint) at init time guarantees the key is valid before the call returns. The daemon thread can still handle refresh and rotation; the synchronous probe just confirms the initial credential is valid.2. Identity invalidation event on deferred auth failure. If the daemon thread auth does fail after init returns (e.g., token revoked mid-session), the SDK should emit an identity invalidation event that upstream agents and orchestrators can intercept. An agent that loses its identity silently mid-session is a trust boundary violation — downstream tools and collaborating agents may have made decisions based on the assumption the agent was authenticated.
From a behavioral trust perspective, an agent that initializes with an invalid API key and then silently fails to report telemetry has a broken attestation chain — its actions cannot be attributed or audited. AgentFolio and SATP track observable telemetry as a trust signal; silent initialization failure creates a gap in that record that looks identical to an agent that simply had no activity.
HhH666-ux commentedon Nov 6, 2026
I reproduced this on
mainwith the reported test (tests/integration/test_auth_flow.py::test_auth_flow_invalid_key):init()returned successfully and theApiServerExceptionnever reached the caller.The fix keeps the background task for async callers, but when
init()runs without a running event loop (the synchronous API), it now authenticates before returning and letsInvalidApiKeyException/ApiServerExceptionpropagate. Other unexpected errors are still swallowed as before, and the happy path is unchanged.Both tests in
tests/integration/test_auth_flow.pypass locally. Opening a PR that links this issue.