{"record":{"id":"7f5e9c93180c9b25","repo":"upstash/context7","slug":"authentication-error","errorCode":"authentication_error","errorMessage":"The auth token provider returned an empty token","messagePattern":"The auth token provider returned an empty token","errorType":"exception","errorClass":"Context7Error","httpStatus":null,"severity":"error","filePath":"packages/sdk/src/http/index.ts","lineNumber":166,"sourceCode":"      const metadata = extractResponseMetadata(response, attempt);\n      this.onResponse?.(metadata);\n      const shouldRetry =\n        canRetry && this.retry.statuses.has(response.status) && attempt < this.retry.retries;\n      if (!shouldRetry) return { response, metadata };\n\n      await response.body?.cancel().catch(() => undefined);\n      await wait(\n        retryDelay(this.retry.backoff(attempt), metadata.rateLimit?.retryAfter),\n        abortState.signal\n      );\n    }\n\n    throw new Error(\"Unreachable retry state\");\n  }\n\n  private headersForToken(authToken: string | undefined): Record<string, string> {\n    if (this.authToken !== undefined && !authToken) {\n      throw new Context7Error(\"The auth token provider returned an empty token\", {\n        code: \"authentication_error\",\n        retryable: false,\n      });\n    }\n\n    return authToken ? { ...this.headers, Authorization: `Bearer ${authToken}` } : this.headers;\n  }\n}\n\nfunction buildUrl(baseUrl: string, method: \"GET\" | \"POST\", request: Context7Request): string {\n  const url = [baseUrl, ...(request.path ?? [])].join(\"/\");\n  if (method !== \"GET\" || !request.query) return url;\n\n  const query = new URLSearchParams();\n  for (const [key, value] of Object.entries(request.query)) {\n    if (value !== undefined) query.append(key, String(value));\n  }\n  const queryString = query.toString();","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/upstash/context7/blob/4416fb855b8f752be735e34f943b5d0762701aad/packages/sdk/src/http/index.ts#L148-L184","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nconst client = new Context7Client({ authToken: () => store.token ?? '' });\n// after\nconst client = new Context7Client({\n  authToken: () => {\n    const t = store.token;\n    if (!t) throw new Error('Not authenticated yet');\n    return t;\n  },\n});","handlingStrategy":"try-catch","validationCode":"const token = typeof authToken === 'function' ? authToken() : authToken;\nif (config.authToken !== undefined && !token) throw new Error('auth token provider returned empty token');","typeGuard":"function hasToken(t: string | undefined | (() => string | undefined)): t is string {\n  const v = typeof t === 'function' ? t() : t;\n  return typeof v === 'string' && v.length > 0;\n}","tryCatchPattern":"try {\n  const data = await client.exec(cmd);\n} catch (e) {\n  if (e instanceof Context7Error && e.code === 'authentication_error' && !e.retryable) {\n    // re-authenticate / refresh token, then rebuild the client\n  } else { throw e; }\n}","preventionTips":["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"],"tags":["authentication","token","http","config"],"backgroundTag":"missing-credentials","analyzedSha":"4416fb855b8f752be735e34f943b5d0762701aad","analyzedAt":"2026-09-16T20:28:07.148Z","contentChangedAt":"2026-09-16T20:28:07.148Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}