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
A missing API key returns 403, but the docs say 401, and the SDKs then raise PermissionDenied instead of AuthenticationError #8
{"detail":{"error_type":"authentication_error","message":"Must supply an API key! Check your request and try again."}} HTTP 403
{"detail":{"error_type":"authentication_error","message":"Must supply an API key! Check your request and try again."}} HTTP 403
{"detail":{"error_type":"authentication_error","message":"Cannot authenticate with the server. Please check your API key and try again."}} HTTP 401
So a missing key gets 403 while an invalid key gets 401, although both carry error_type: "authentication_error".
Why it matters
The Python SDK (errors.py) and the JS SDK (errors.ts) map exceptions by status only. A deployment that forgot to set TYPESAFE_API_KEY raises PermissionDeniedError, and code that catches AuthenticationError for "fix your key" handling misses it.
Suggested fix
Return 401 for a missing key, as documented. Or list 403 in the error table as "no API key supplied".
Optionally, have the SDKs map detail.error_type == "authentication_error" to AuthenticationError regardless of status. This is more robust than keying on the status alone.
Because the server responds with HTTP 403 for missing or unsupplied credentials with the body:
{"detail":{"error_type":"authentication_error","message":"Must supply an API key! Check your request and try again."}}
The client raises PermissionDeniedError (or TypeSafePermissionDeniedError). Standard error-handling middleware catching AuthenticationError (e.g. to prompt the user to re-authenticate or log credential misconfigurations) is bypassed, and the error falls through to generic permission/authorization failure handlers.
3. Suggested Fix
In addition to returning HTTP 401 at the gateway for unauthenticated requests as documented in the API reference, both SDKs can inspect the structured error payload in api_error / APIError.fromResponse:
If body.detail.error_type === "authentication_error" (or body.error_type === "authentication_error"), map to AuthenticationError / TypeSafeAuthenticationError regardless of whether the status is 401 or 403. This protects clients against gateway differences while remaining compatible with status-only fallbacks.
Activity
aoright commentedon Sep 23, 2026
I traced the error mapping paths across both official SDKs to see how this impacts client code:
1. Current SDK Exception Mapping
Both SDKs currently resolve error subclasses exclusively by HTTP status code:
src/typesafe_sdk/_core/errors.py:198-200):src/errors.ts:69-79):2. Client Impact
Because the server responds with HTTP 403 for missing or unsupplied credentials with the body:
{"detail":{"error_type":"authentication_error","message":"Must supply an API key! Check your request and try again."}}The client raises
PermissionDeniedError(orTypeSafePermissionDeniedError). Standard error-handling middleware catchingAuthenticationError(e.g. to prompt the user to re-authenticate or log credential misconfigurations) is bypassed, and the error falls through to generic permission/authorization failure handlers.3. Suggested Fix
In addition to returning HTTP 401 at the gateway for unauthenticated requests as documented in the API reference, both SDKs can inspect the structured error payload in
api_error/APIError.fromResponse:If
body.detail.error_type === "authentication_error"(orbody.error_type === "authentication_error"), map toAuthenticationError/TypeSafeAuthenticationErrorregardless of whether the status is 401 or 403. This protects clients against gateway differences while remaining compatible with status-only fallbacks.