{"record":{"id":"9c2c60791ac1e34e","repo":"continuedev/continue","slug":"asksage-adapter-missing-apikey-provide-it-in-you","errorCode":null,"errorMessage":"AskSage adapter: missing apiKey. Provide it in your configuration.","messagePattern":"AskSage adapter: missing apiKey\\. Provide it in your configuration\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/openai-adapters/src/apis/AskSage.ts","lineNumber":74,"sourceCode":"  private email?: string;\n  private sessionTokenPromise: Promise<string> | null = null;\n  private tokenTimestamp: number = 0;\n  private fetchFn: typeof fetch;\n\n  constructor(private config: AskSageConfig) {\n    this.apiBase = config.apiBase ?? DEFAULT_API_URL;\n    this.userApiUrl = config.env?.userApiUrl ?? DEFAULT_USER_API_URL;\n    this.apiKey = config.apiKey;\n    this.email = config.env?.email;\n    this.fetchFn = customFetch(config.requestOptions);\n  }\n\n  /**\n   * Get session token from API key + email, or use API key directly\n   */\n  private async getSessionToken(): Promise<string> {\n    if (!this.apiKey) {\n      throw new Error(\n        \"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) {","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/continuedev/continue/blob/5522c6f44ca0ac3528b37244818fbfa39b5af470/packages/openai-adapters/src/apis/AskSage.ts#L56-L92","documentation":"The AskSage adapter needs an API key to authenticate (either directly or exchanged for a session token with email). getSessionToken throws immediately when apiKey is falsy, meaning the adapter was constructed without a key. Check your config/environment for the AskSage API key.","triggerScenarios":"Constructing the AskSage adapter with empty/undefined apiKey and invoking any chat completion (which calls getToken→getSessionToken).","commonSituations":"Missing ASKSAUGE_API_KEY-style env var; typo'd config key name; key loaded from a .env file that isn't being read in the current environment (CI, prod).","solutions":["Set the apiKey in the adapter constructor/config from your environment","Verify the env var name and that it's loaded (print process.env keys in CI)","Add a startup assertion that apiKey is non-empty before first use"],"exampleFix":"// before\nconst api = new AskSage({ apiKey: process.env.ASKSAGE_API_KEY /* undefined */ });\n\n// after\nconst apiKey = process.env.ASKSAGE_API_KEY;\nif (!apiKey) throw new Error('ASKSAGE_API_KEY not set');\nconst api = new AskSage({ apiKey });","handlingStrategy":"validation","validationCode":"if (!process.env.ASKSAGE_API_KEY) throw new Error('ASKSAGE_API_KEY not set');","typeGuard":"function hasAskSageCreds(cfg: { apiKey?: string; email?: string }): boolean {\n  return typeof cfg.apiKey === 'string' && cfg.apiKey.length > 0;\n}","tryCatchPattern":"try { await api.chatCompletionNonStream(body, signal); }\ncatch (e) { if (/missing apiKey/.test(String(e))) { failFast('Configure ASKSAGE_API_KEY'); } throw e; }","preventionTips":["Assert required env vars at startup, not on first request","Use a config schema validator (zod) for adapter construction"],"tags":["asksage","authentication","missing-api-key","config"],"backgroundTag":"missing-api-key","analyzedSha":"5522c6f44ca0ac3528b37244818fbfa39b5af470","analyzedAt":"2026-08-27T11:28:54.683Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}