{"record":{"id":"48e27f185c06f43f","repo":"upstash/context7","slug":"api-key-should-start-with-api-key-prefix","errorCode":null,"errorMessage":"API key should start with '${API_KEY_PREFIX}'","messagePattern":"API key should start with '(.+?)'","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/sdk/src/client.ts","lineNumber":38,"sourceCode":"  RateLimitMetadata,\n  RetryConfig,\n} from \"@http\";\nexport * from \"@error\";\n\nexport class Context7 {\n  private readonly httpClient: HttpClient;\n\n  constructor(config: Context7Config = {}) {\n    const apiKey = config.apiKey || getEnvironmentApiKey();\n\n    if (!apiKey) {\n      throw new Context7Error(\n        \"API key is required. Pass it in the config or set CONTEXT7_API_KEY environment variable.\"\n      );\n    }\n\n    if (!apiKey.startsWith(API_KEY_PREFIX)) {\n      console.warn(`API key should start with '${API_KEY_PREFIX}'`);\n    }\n\n    this.httpClient = new HttpClient({\n      baseUrl: config.baseUrl ?? DEFAULT_BASE_URL,\n      headers: {\n        ...withoutAuthorizationHeader(config.headers),\n        Authorization: `Bearer ${apiKey}`,\n      },\n      retry: config.retry,\n      cache: config.cache ?? \"no-store\",\n      timeout: config.timeout,\n      signal: config.signal,\n      keepAlive: config.keepAlive,\n      fetch: config.fetch,\n      onResponse: config.onResponse,\n    });\n  }\n","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/upstash/context7/blob/80e681a507c5287bc12e483367c40754e29461b9/packages/sdk/src/client.ts#L20-L56","documentation":"console.warn from the Context7Client constructor (packages/sdk/src/client.ts): an API key was found (config.apiKey or CONTEXT7_API_KEY) but it does not start with the expected 'ctx7sk' prefix. The client still constructs and sends the key as a Bearer token, so requests will typically fail downstream with 401/403 — the warn is an early hint that the key is wrong-truncated-or-from-another-provider.","triggerScenarios":"Set CONTEXT7_API_KEY to an OpenAI/Anthropic/other-vendor key by mistake; copy-pasted the key with a leading quote, space, or trailing newline (e.g. from an .env with quoted values or a clipboard artifact); truncated key; legacy or rotated key format.","commonSituations":"Shared .env files where the variable was pasted with quotes (`CONTEXT7_API_KEY=\"ctx7sk-...\"`) so the value starts with a quote; CI secrets with an invisible trailing \\n; users reusing the wrong vendor's key out of muscle memory; keys copied from a dashboard diff view picking up line numbers.","solutions":["Regenerate/copy the key from the Context7 dashboard and confirm it starts with `ctx7sk`","Strip whitespace/newlines when loading: `process.env.CONTEXT7_API_KEY?.trim()`","Inspect the env var for invisible characters: `printenv CONTEXT7_API_KEY | cat -A`","If set in shell profile or .env, remove surrounding quotes and re-source"],"exampleFix":"// before\nconst client = new Context7Client(); // CONTEXT7_API_KEY=\"ctx7sk-...\" (with quotes) -> warn\n\n// after\nconst apiKey = process.env.CONTEXT7_API_KEY?.trim().replace(/^\"|\"$/g, \"\");\nconst client = new Context7Client({ apiKey });","handlingStrategy":"validation","validationCode":"// Validate and normalize the key BEFORE constructing the client\nconst rawKey = (config.apiKey ?? process.env.CONTEXT7_API_KEY ?? \"\").trim();\nif (!rawKey) {\n  throw new Error(\"CONTEXT7_API_KEY is required\");\n}\nif (!rawKey.startsWith(\"ctx7sk\")) {\n  throw new Error(\n    `Context7 API key must start with 'ctx7sk' (got '${rawKey.slice(0, 6)}...') — check for stray quotes/whitespace or a wrong-vendor key`\n  );\n}\nconst client = new Context7Client({ apiKey: rawKey });","typeGuard":"function isPlausibleContext7Key(key: unknown): key is string {\n  return (\n    typeof key === \"string\" &&\n    key === key.trim() && // no surrounding whitespace\n    !key.includes('\"') &&\n    key.startsWith(\"ctx7sk\") &&\n    key.length > \"ctx7sk\".length + 8 // prefix plus a non-trivial body\n  );\n}","tryCatchPattern":null,"preventionTips":["Store the key unquoted in .env and trim() it at load time","Name vendor keys distinctly (CONTEXT7_API_KEY vs OPENAI_API_KEY) so the wrong one is never picked","Run `printenv CONTEXT7_API_KEY | cat -A` once after setup to catch invisible characters","Treat the prefix warn as a pre-flight failure — fix the key before debugging 401s downstream"],"tags":["sdk","authentication","api-key","env-var","config"],"backgroundTag":"invalid-api-key-format","analyzedSha":"80e681a507c5287bc12e483367c40754e29461b9","analyzedAt":"2026-08-18T18:00:18.510Z","contentChangedAt":"2026-08-18T18:00:18.510Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}