{"record":{"id":"d7c185f43e49fa73","repo":"santifer/career-ops","slug":"openrouter-api-key-not-found-copy-env-example-to","errorCode":null,"errorMessage":"OPENROUTER_API_KEY not found.\nCopy .env.example to .env and add your API key.\nFree key: https://openrouter.ai","messagePattern":"OPENROUTER_API_KEY not found\\.\nCopy \\.env\\.example to \\.env and add your API key\\.\nFree key: https://openrouter\\.ai","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"openrouter-runner.mjs","lineNumber":224,"sourceCode":"// Providers that support caching (Anthropic, Gemini, …) reuse the prefix across\n// back-to-back calls within the cache TTL; providers that don't simply ignore\n// the field, so this is a safe passthrough that never changes the prompt text.\nexport function buildCachedSystemMessage(systemPrompt) {\n  return {\n    role: 'system',\n    content: [\n      { type: 'text', text: systemPrompt, cache_control: { type: 'ephemeral' } },\n    ],\n  };\n}\n\n// ---------------------------------------------------------------------------\n// OpenRouter API call — automatic model rotation with fallback\n// ---------------------------------------------------------------------------\nasync function callOpenRouter(systemPrompt, userMessage) {\n  const key = process.env.OPENROUTER_API_KEY;\n  if (!key) {\n    throw new Error(\n      'OPENROUTER_API_KEY not found.\\n' +\n      'Copy .env.example to .env and add your API key.\\n' +\n      'Free key: https://openrouter.ai'\n    );\n  }\n\n  const pinnedModel = process.env.CAREER_OPS_MODEL;\n  if (pinnedModel) {\n    activeModel = pinnedModel;\n    process.stdout.write(`[model] ${pinnedModel} (pinned) ... `);\n    const body = JSON.stringify({\n      model: pinnedModel,\n      messages: [\n        buildCachedSystemMessage(systemPrompt),\n        { role: 'user', content: userMessage },\n      ],\n      max_tokens: MAX_TOKENS,\n    });","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/santifer/career-ops/blob/aac998c7ed7248ea853b720ceeb1fdbeb322fc5d/openrouter-runner.mjs#L206-L242","documentation":"Thrown at the top of callOpenRouter() when `process.env.OPENROUTER_API_KEY` is undefined or empty. The library refuses to make any API call without credentials. The multi-line message includes exact setup steps and a link to get a free key.","triggerScenarios":"Any evaluation run where the environment lacks OPENROUTER_API_KEY: .env file missing, .env present but not loaded before this module reads process.env, variable misspelled (OPEN_ROUTER_API_KEY), or key defined only in shell profile of a different user/session.","commonSituations":"Fresh clone without `cp .env.example .env`; CI/CD job where the secret was not injected into env; dotenv imported after openrouter-runner; running via systemd/cron where interactive shell env vars are absent.","solutions":["Copy .env.example to .env and paste a key from https://openrouter.ai (free tier available).","Confirm the dotenv loader runs BEFORE openrouter-runner is imported (import order matters in ESM).","Check the variable name is exactly OPENROUTER_API_KEY with no surrounding quotes or whitespace in .env.","In CI, verify the secret is exposed to the job's environment, not just the repo settings.","Test with `echo ${OPENROUTER_API_KEY:+set}` in the same shell/runner that executes the script."],"exampleFix":"// before (runner imported before env is loaded)\nimport { callOpenRouter } from './openrouter-runner.mjs';\nimport dotenv from 'dotenv';\ndotenv.config();\n// after\nimport dotenv from 'dotenv';\ndotenv.config();\nimport { callOpenRouter } from './openrouter-runner.mjs';","handlingStrategy":"validation","validationCode":"import 'dotenv/config'; // must run before runner modules\nif (!process.env.OPENROUTER_API_KEY?.trim()) {\n  throw new Error('OPENROUTER_API_KEY missing — copy .env.example to .env and add a key from https://openrouter.ai');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await callOpenRouter(systemPrompt, userMessage);\n} catch (err) {\n  if (err.message.includes('OPENROUTER_API_KEY not found')) {\n    console.error('Credentials missing. Setup: cp .env.example .env && add key from https://openrouter.ai');\n    process.exit(1);\n  }\n  throw err;\n}","preventionTips":["Put `import 'dotenv/config'` as the first import of every entrypoint.","Validate required env vars at startup with an assert-env helper.","In CI, mark OPENROUTER_API_KEY as a required secret and fail fast when absent.","Avoid stray quotes/whitespace around the value in .env."],"tags":["openrouter","api-key","environment","configuration"],"backgroundTag":"missing-api-key","analyzedSha":"aac998c7ed7248ea853b720ceeb1fdbeb322fc5d","analyzedAt":"2026-09-16T06:35:29.214Z","contentChangedAt":"2026-09-16T06:35:29.214Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}