{"record":{"id":"11a8a1851dcf7732","repo":"continuedev/continue","slug":"error-getting-access-token-json-stringify-data-11a8a1","errorCode":null,"errorMessage":"Error getting access token:  + JSON.stringify(data)","messagePattern":"Error getting access token:  \\+ JSON\\.stringify\\(data\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/openai-adapters/src/apis/AskSage.ts","lineNumber":93,"sourceCode":"        \"AskSage adapter: missing apiKey. Provide it in your configuration.\",\n      );\n    }\n\n    // If no email, use API key directly\n    if (!this.email || this.email.length === 0) {\n      return this.apiKey;\n    }\n\n    const url = this.userApiUrl.replace(/\\/$/, \"\") + \"/get-token-with-api-key\";\n    const res = await this.fetchFn(url, {\n      method: \"POST\",\n      headers: { \"Content-Type\": \"application/json\" },\n      body: JSON.stringify({ email: this.email, api_key: this.apiKey }),\n    });\n\n    const data = (await res.json()) as AskSageTokenResponse;\n    if (parseInt(String(data.status)) !== 200) {\n      throw new Error(\"Error getting access token: \" + JSON.stringify(data));\n    }\n    return data.response.access_token;\n  }\n\n  /**\n   * Get cached token or refresh if expired\n   */\n  private async getToken(): Promise<string> {\n    if (\n      !this.sessionTokenPromise ||\n      Date.now() - this.tokenTimestamp > TOKEN_TTL\n    ) {\n      this.sessionTokenPromise = this.getSessionToken();\n      this.tokenTimestamp = Date.now();\n      // Clear cache on failure so transient errors don't prevent retries\n      this.sessionTokenPromise.catch(() => {\n        this.clearTokenCache();\n      });","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/continuedev/continue/blob/5522c6f44ca0ac3528b37244818fbfa39b5af470/packages/openai-adapters/src/apis/AskSage.ts#L75-L111","documentation":"AskSage's token endpoint returned a non-200 status payload when exchanging email+api_key for an access_token. The adapter throws with the full JSON response so the status/message fields are visible. The credentials were rejected or the token service is unavailable.","triggerScenarios":"Calling AskSage chat with email+apiKey configured; the POST to the token endpoint returns {status: 401/403/500,...} — invalid key, wrong email, expired key, or service outage.","commonSituations":"Revoked or mistyped AskSage API key; email not matching the account that owns the key; AskSage auth service downtime or changed response schema (status no longer numeric 200).","solutions":["Verify the apiKey and email pair against the AskSage dashboard","Regenerate the API key if revoked or expired","Check the JSON in the error message for the exact status/message; 5xx means retry later","If using apiKey-only auth, omit email so the key is used directly"],"exampleFix":"// before\nconst api = new AskSage({ apiKey: KEY, email: 'wrong@ex.com' });\n\n// after\nconst api = new AskSage({ apiKey: KEY }); // or email that matches the key's account","handlingStrategy":"retry","validationCode":"// Pre-flight: verify creds by hitting the token endpoint once at startup\nconst res = await fetch(TOKEN_URL, { method: 'POST', body: JSON.stringify({ email, api_key }) });\nif (!res.ok) throw new Error('AskSage credentials invalid');","typeGuard":null,"tryCatchPattern":"try { await api.chatCompletionNonStream(body, signal); }\ncatch (e) { if (/Error getting access token/.test(String(e))) { /* fix creds; do NOT blind-retry */ throw e; } throw e; }","preventionTips":["Validate credentials at deployment time with a preflight token call","Keep email and apiKey paired from the same account; regenerate keys on 401"],"tags":["asksage","authentication","token-exchange"],"backgroundTag":"auth-token-request-failed","analyzedSha":"5522c6f44ca0ac3528b37244818fbfa39b5af470","analyzedAt":"2026-08-27T11:28:54.683Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}