{"record":{"id":"ca401c7d99427211","repo":"abhigyanpatwari/GitNexus","slug":"openrouter-api-key-is-required-but-was-not-provide","errorCode":null,"errorMessage":"OpenRouter API key is required but was not provided","messagePattern":"OpenRouter API key is required but was not provided","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"gitnexus-web/src/core/llm/agent.ts","lineNumber":257,"sourceCode":"        // This is critical for agentic workflows with tool calls\n        numCtx: 32768,\n      });\n    }\n\n    case 'openrouter': {\n      const openRouterConfig = config as OpenRouterConfig;\n\n      // Debug logging\n      if (import.meta.env.DEV) {\n        console.log('🌐 OpenRouter config:', {\n          hasApiKey: !!openRouterConfig.apiKey,\n          model: openRouterConfig.model,\n          baseUrl: openRouterConfig.baseUrl,\n        });\n      }\n\n      if (!openRouterConfig.apiKey || openRouterConfig.apiKey.trim() === '') {\n        throw new Error('OpenRouter API key is required but was not provided');\n      }\n\n      return new ChatOpenAI({\n        openAIApiKey: openRouterConfig.apiKey,\n        apiKey: openRouterConfig.apiKey, // Fallback for some versions\n        modelName: openRouterConfig.model,\n        temperature: openRouterConfig.temperature ?? 0.1,\n        maxTokens: openRouterConfig.maxTokens,\n        configuration: {\n          apiKey: openRouterConfig.apiKey, // Ensure client receives it\n          baseURL: openRouterConfig.baseUrl ?? DEFAULT_OPENROUTER_BASE_URL,\n        },\n        streaming: true,\n      });\n    }\n\n    case 'minimax': {\n      const minimaxConfig = config as MiniMaxConfig;","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/gitnexus-web/src/core/llm/agent.ts#L239-L275","documentation":"Thrown by createChatModel() in the 'openrouter' provider branch when openRouterConfig.apiKey is falsy or whitespace-only. OpenRouter is accessed through a ChatOpenAI wrapper pointed at the OpenRouter base URL; without a key the wrapper would 401 on first call, so this guard fails fast at construction. Note the DEV-mode debug log prints only hasApiKey (boolean), never the key value.","triggerScenarios":"Calling createChatModel({ provider: 'openrouter', apiKey: undefined | '' | '   ', ... }). The check is !apiKey || apiKey.trim() === ''.","commonSituations":"The OpenRouter key wasn't entered in settings; the env var backing it is unset in the deployed environment; switching provider to openrouter without provisioning a key from openrouter.ai.","solutions":["Obtain a key from openrouter.ai and enter it in the provider settings","Ensure the key is non-empty and non-whitespace","After setting it, re-create the agent (createChatModel runs at agent construction, so a stale agent won't pick up a new key)","If no OpenRouter key is available, switch to a provider that doesn't require one (ollama)"],"exampleFix":"// before\ncreateChatModel({ provider: 'openrouter', apiKey: '', model: 'anthropic/claude-3.5-sonnet' }); // throws\n\n// after\ncreateChatModel({ provider: 'openrouter', apiKey: userKey, model: 'anthropic/claude-3.5-sonnet' });","handlingStrategy":"validation","validationCode":"function hasOpenRouterKey(cfg: { apiKey?: string }): boolean {\n  return typeof cfg.apiKey === 'string' && cfg.apiKey.trim().length > 0;\n}\nif (cfg.provider === 'openrouter' && !hasOpenRouterKey(cfg)) {\n  throw new Error('Configure an OpenRouter API key (from openrouter.ai)');\n}","typeGuard":"function isOpenRouterConfigReady(cfg: unknown): cfg is { provider: 'openrouter'; apiKey: string } {\n  return typeof cfg === 'object' && cfg !== null\n    && (cfg as any).provider === 'openrouter'\n    && typeof (cfg as any).apiKey === 'string'\n    && (cfg as any).apiKey.trim().length > 0;\n}","tryCatchPattern":"try {\n  createChatModel({ provider: 'openrouter', apiKey, model });\n} catch (e) {\n  if (e instanceof Error && /OpenRouter API key is required/.test(e.message)) {\n    promptUserForKey('openrouter');\n    return;\n  }\n  throw e;\n}","preventionTips":["Obtain keys from openrouter.ai — OpenRouter proxies many providers behind one key","Store keys in the settings UI so they survive reloads; re-create the agent after updating","Note the DEV debug log prints only hasApiKey (boolean), never the key — safe to leave in dev","If no key, switch to ollama (local, no key) or another provider"],"tags":["llm","openrouter","config","api-key"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}