upstash/context7 · error · Context7Error
authentication_error
authentication_error
Error message
The auth token provider returned an empty token
What it means
headersForToken builds request headers by resolving the auth token from a token provider. If a static authToken was configured but the provider dynamically returned an empty/undefined token, the client throws a non-retryable Context7Error with code authentication_error, because silently sending an unauthenticated request would fail downstream anyway.
Solutions
- Make the token provider return a valid non-empty string or fail loudly before requests start
- If the token is dynamic, ensure the provider awaits token refresh and throws a meaningful error when the token cannot be obtained
- Do not configure a static authToken if you cannot guarantee a token; omit it and rely on apiKey authentication
- Check provider ordering: ensure authentication/login completes before the client issues requests
Example fix
// before
const client = new Context7Client({ authToken: () => store.token ?? '' });
// after
const client = new Context7Client({
authToken: () => {
const t = store.token;
if (!t) throw new Error('Not authenticated yet');
return t;
},
}); Defensive patterns
Strategy: try-catch
Validate before calling
const token = typeof authToken === 'function' ? authToken() : authToken;
if (config.authToken !== undefined && !token) throw new Error('auth token provider returned empty token'); Type guard
function hasToken(t: string | undefined | (() => string | undefined)): t is string {
const v = typeof t === 'function' ? t() : t;
return typeof v === 'string' && v.length > 0;
} Try / catch
try {
const data = await client.exec(cmd);
} catch (e) {
if (e instanceof Context7Error && e.code === 'authentication_error' && !e.retryable) {
// re-authenticate / refresh token, then rebuild the client
} else { throw e; }
} Prevention
- Ensure login/token refresh completes before the client issues its first request
- Have the token provider throw a clear error instead of returning an empty string
- Avoid sync providers wrapping async token lookups — they silently return undefined
- Because this error is non-retryable, do not blanket-retry; fix the token source instead
When it happens
Trigger: Configuring authToken as a function () => string whose return value is '' or undefined at request time (e.g. reading a token from a store that is not yet populated, an expired/cleared session, or an async provider whose value was not awaited).
Common situations: Token read from storage/cache before login completes; token refresh job failing and leaving an empty string; passing a sync function wrapping an async token fetch (returning undefined); race where the provider is called before credentials load.
Related errors
- Authentication is required. Pass apiKey or authToken, or…
- Context7UrlError
- errorBody.error || errorBody.message || res.statusText
- -32001
- A fetch implementation is required
AI-assisted analysis of upstash/context7@4416fb855b (2026-09-16).
Data as JSON: /api/errors/7f5e9c93180c9b25.
Report an issue: GitHub.
Appendix: source
Thrown at packages/sdk/src/http/index.ts:166
const metadata = extractResponseMetadata(response, attempt);
this.onResponse?.(metadata);
const shouldRetry =
canRetry && this.retry.statuses.has(response.status) && attempt < this.retry.retries;
if (!shouldRetry) return { response, metadata };
await response.body?.cancel().catch(() => undefined);
await wait(
retryDelay(this.retry.backoff(attempt), metadata.rateLimit?.retryAfter),
abortState.signal
);
}
throw new Error("Unreachable retry state");
}
private headersForToken(authToken: string | undefined): Record<string, string> {
if (this.authToken !== undefined && !authToken) {
throw new Context7Error("The auth token provider returned an empty token", {
code: "authentication_error",
retryable: false,
});
}
return authToken ? { ...this.headers, Authorization: `Bearer ${authToken}` } : this.headers;
}
}
function buildUrl(baseUrl: string, method: "GET" | "POST", request: Context7Request): string {
const url = [baseUrl, ...(request.path ?? [])].join("/");
if (method !== "GET" || !request.query) return url;
const query = new URLSearchParams();
for (const [key, value] of Object.entries(request.query)) {
if (value !== undefined) query.append(key, String(value));
}
const queryString = query.toString();View on GitHub (pinned to 4416fb855b)