-
Notifications
You must be signed in to change notification settings - Fork 2.6k
fix: resolve OpenRouter 401 authentication errors #6460
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -97,8 +97,14 @@ export async function getOpenRouterModels(options?: ApiHandlerOptions): Promise< | |
| const models: Record<string, ModelInfo> = {} | ||
| const baseURL = options?.openRouterBaseUrl || "https://openrouter.ai/api/v1" | ||
|
|
||
| // Prepare headers with API key if available | ||
| const headers: Record<string, string> = {} | ||
| if (options?.openRouterApiKey) { | ||
| headers.Authorization = `Bearer ${options.openRouterApiKey}` | ||
| } | ||
|
|
||
| try { | ||
| const response = await axios.get<OpenRouterModelsResponse>(`${baseURL}/models`) | ||
| const response = await axios.get<OpenRouterModelsResponse>(`${baseURL}/models`, { headers }) | ||
| const result = openRouterModelsResponseSchema.safeParse(response.data) | ||
| const data = result.success ? result.data.data : response.data.data | ||
|
|
||
|
|
@@ -118,6 +124,10 @@ export async function getOpenRouterModels(options?: ApiHandlerOptions): Promise< | |
| }) | ||
| } | ||
| } catch (error) { | ||
| if (axios.isAxiosError(error) && error.response?.status === 401) { | ||
| console.error("OpenRouter API authentication failed. Please check your API key.") | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is the duplication of the same error message in both console.error and throw new Error intentional? Could we streamline this to avoid redundant logging? |
||
| throw new Error("OpenRouter API authentication failed. Please check your API key.") | ||
| } | ||
| console.error( | ||
| `Error fetching OpenRouter models: ${JSON.stringify(error, Object.getOwnPropertyNames(error), 2)}`, | ||
| ) | ||
|
|
@@ -137,8 +147,16 @@ export async function getOpenRouterModelEndpoints( | |
| const models: Record<string, ModelInfo> = {} | ||
| const baseURL = options?.openRouterBaseUrl || "https://openrouter.ai/api/v1" | ||
|
|
||
| // Prepare headers with API key if available | ||
| const headers: Record<string, string> = {} | ||
| if (options?.openRouterApiKey) { | ||
| headers.Authorization = `Bearer ${options.openRouterApiKey}` | ||
| } | ||
|
|
||
| try { | ||
| const response = await axios.get<OpenRouterModelEndpointsResponse>(`${baseURL}/models/${modelId}/endpoints`) | ||
| const response = await axios.get<OpenRouterModelEndpointsResponse>(`${baseURL}/models/${modelId}/endpoints`, { | ||
| headers, | ||
| }) | ||
| const result = openRouterModelEndpointsResponseSchema.safeParse(response.data) | ||
| const data = result.success ? result.data.data : response.data.data | ||
|
|
||
|
|
@@ -157,6 +175,10 @@ export async function getOpenRouterModelEndpoints( | |
| }) | ||
| } | ||
| } catch (error) { | ||
| if (axios.isAxiosError(error) && error.response?.status === 401) { | ||
| console.error("OpenRouter API authentication failed. Please check your API key.") | ||
| throw new Error("OpenRouter API authentication failed. Please check your API key.") | ||
| } | ||
| console.error( | ||
| `Error fetching OpenRouter model endpoints: ${JSON.stringify(error, Object.getOwnPropertyNames(error), 2)}`, | ||
| ) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -66,6 +66,11 @@ export class OpenRouterHandler extends BaseProvider implements SingleCompletionH | |
| const baseURL = this.options.openRouterBaseUrl || "https://openrouter.ai/api/v1" | ||
| const apiKey = this.options.openRouterApiKey ?? "not-provided" | ||
|
|
||
| // Validate API key format | ||
| if (apiKey === "not-provided" || !apiKey || apiKey.trim() === "") { | ||
| console.warn("OpenRouter API key is missing or invalid. This may cause authentication errors.") | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The API key validation happens in the constructor but API calls occur later. Could we consider more strict validation (e.g., checking expected prefixes or length) to catch format issues earlier? |
||
| } | ||
|
|
||
| this.client = new OpenAI({ baseURL, apiKey, defaultHeaders: DEFAULT_HEADERS }) | ||
| } | ||
|
|
||
|
|
@@ -175,11 +180,16 @@ export class OpenRouterHandler extends BaseProvider implements SingleCompletionH | |
|
|
||
| public async fetchModel() { | ||
| const [models, endpoints] = await Promise.all([ | ||
| getModels({ provider: "openrouter" }), | ||
| getModels({ | ||
| provider: "openrouter", | ||
| apiKey: this.options.openRouterApiKey, | ||
| baseUrl: this.options.openRouterBaseUrl, | ||
| }), | ||
| getModelEndpoints({ | ||
| router: "openrouter", | ||
| modelId: this.options.openRouterModelId, | ||
| endpoint: this.options.openRouterSpecificProvider, | ||
| ...this.options, | ||
| }), | ||
| ]) | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -106,7 +106,7 @@ export const getModelMaxOutputTokens = ({ | |
| // GetModelsOptions | ||
|
|
||
| export type GetModelsOptions = | ||
| | { provider: "openrouter" } | ||
| | { provider: "openrouter"; apiKey?: string; baseUrl?: string } | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The GetModelsOptions type makes apiKey optional, but the error handling suggests it's expected. Could we make this more explicit in the type definition for better type safety? |
||
| | { provider: "glama" } | ||
| | { provider: "requesty"; apiKey?: string } | ||
| | { provider: "unbound"; apiKey?: string } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The axios import was added here but wasn't present in the original file structure. Could you verify this import is actually needed and properly available in the test environment?