Skip to content

OpenRouter and Groq API keys return 401 despite working in curl (Continue v1.0.13) #6191

Open
@leantos

Description

@leantos

Before submitting your bug report

Relevant environment info

- OS: Windows
- Continue version:v1.0.13
- IDE version:VSCode 1.101.0
- Model:llama-3-70b-instruct
- config:
  
name: openrouter-test
version: 0.0.1

models:
  - id: llama3-openrouter
    name: LLaMA 3 (OpenRouter)
    provider: openrouter
    model: meta-llama/llama-3-70b-instruct
    api_key: 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

assistants: []

  
  OR link to assistant in Continue hub:

Description

🐛 Bug Report: OpenRouter and Groq API keys return 401 despite working in curl (Continue v1.0.13)

Summary

I'm unable to use OpenRouter or Groq with Continue v1.0.13.


✅ What works

When I test the key manually using PowerShell:

Invoke-RestMethod -Uri "https://openrouter.ai/api/v1/models" `
  -Headers @{ "Authorization" = "Bearer sk-or-..." }

...I get a valid list of models.


❌ What doesn’t work

Using the same key in config.yaml, Continue fails with:

{"message":"No auth credentials found","code":401}

📄 Config.yaml

name: openrouter-test
version: 0.0.1

models:
  - id: llama3-openrouter
    name: LLaMA 3 (OpenRouter)
    provider: openrouter
    model: meta-llama/llama-3-70b-instruct
    api_key: sk-or-...
assistants: []

🔍 What I’ve tried

  • ✅ Confirmed API key works in PowerShell / curl
  • ✅ Cleared Continue cache (AppData\Roaming\Code\User\globalStorage\continue.continue)
  • ✅ Reloaded VS Code window
  • ✅ Tried both openrouter and groq providers
  • ✅ Renamed model entries
  • ❌ Still get 401 error inside Continue

🔧 Environment

  • VS Code version: 1.89.x
  • Continue extension: v1.0.13
  • OS: Windows 10

💡 What I suspect

This may be a regression in how Continue sends API keys for non-OpenAI providers (Groq, OpenRouter). Might be a formatting/header issue.


Let me know if there's a patch, workaround, or if you'd like logs.

Thanks!

To reproduce

  1. Edit yaml
  2. Configure groq
  3. Configure open-router
  4. check if response works or api key is invalid

Log output

index.js:1508 Object
index.js:1508 Object
index.js:313 CONTENT hi
index.js:313 CONTENT hi
workbench.desktop.main.js:sourcemap:1281 [Extension Host] Error: HTTP 401 Unauthorized from https://openrouter.ai/api/v1/chat/completions

{"error":{"message":"No auth credentials found","code":401}}
    at customFetch2 (c:\Users\Tom\.vscode\extensions\continue.continue-1.0.13-win32-x64\out\extension.js:140356:21)
    at processTicksAndRejections (node:internal/process/task_queues:105:5)
    at withExponentialBackoff (c:\Users\Tom\.vscode\extensions\continue.continue-1.0.13-win32-x64\out\extension.js:136076:27)
    at OpenRouter._streamChat (c:\Users\Tom\.vscode\extensions\continue.continue-1.0.13-win32-x64\out\extension.js:141183:26)
    at OpenRouter._streamComplete (c:\Users\Tom\.vscode\extensions\continue.continue-1.0.13-win32-x64\out\extension.js:141111:26)
    at OpenRouter.streamChat (c:\Users\Tom\.vscode\extensions\continue.continue-1.0.13-win32-x64\out\extension.js:140741:30)
    at llmStreamChat (c:\Users\Tom\.vscode\extensions\continue.continue-1.0.13-win32-x64\out\extension.js:648352:17)
    at ud.handleMessage [as value] (c:\Users\Tom\.vscode\extensions\continue.continue-1.0.13-win32-x64\out\extension.js:666560:29)
workbench.desktop.main.js:sourcemap:35   ERR [Extension Host] Error handling webview message: {
  "msg": {
    "messageId": "8b4a03ba-8d2d-46ee-9078-f0f6641ad1bf",
    "messageType": "llm/streamChat",
    "data": {
      "completionOptions": {},
      "title": "LLaMA 3 (OpenRouter)",
      "messages": [
        {
          "role": "system",
          "content": "<important_rules>\n  You are in chat mode.\n\n  If the user asks to make changes to files offer that they can use the Apply Button on the code block, or switch to Agent Mode to make the suggested updates automatically.\n  If needed consisely explain to the user they can switch to agent mode using the Mode Selector dropdown and provide no other details.\n\n  Always include the language and file name in the info string when you write code blocks.\n  If you are editing \"src/main.py\" for example, your code block should start with ' src/main.py'\n\n  When addressing code modification requests, present a concise code snippet that\n  emphasizes only the necessary changes and uses abbreviated placeholders for\n  unmodified sections. For example:\n\n   /path/to/file\n  // ... existing code ...\n\n  {{ modified code here }}\n\n  // ... existing code ...\n\n  {{ another modification }}\n\n  // ... rest of code ...\n  \n\n  In existing files, you should always restate the function or class that the snippet belongs to:\n\n   /path/to/file\n  // ... existing code ...\n\n  function exampleFunction() {\n    // ... existing code ...\n\n    {{ modified code here }}\n\n    // ... rest of function ...\n  }\n\n  // ... rest of code ...\n  \n\n  Since users have access to their complete file, they prefer reading only the\n  relevant modifications. It's perfectly acceptable to omit unmodified portions\n  at the beginning, middle, or end of files using these \"lazy\" comments. Only\n  provide the complete file when explicitly requested. Include a concise explanation\n  of changes unless the user specifically asks for code only.\n\n</important_rules>"
        },
        {
          "role": "user",
          "content": [
            {
              "type": "text",
              "text": "hi"
            }
          ]
        },
        {
          "role": "assistant",
          "content": ""
        }
      ]
    }
  }
}

Error: HTTP 401 Unauthorized from https://openrouter.ai/api/v1/chat/completions

{"error":{"message":"No auth credentials found","code":401}}
error @ workbench.desktop.main.js:sourcemap:35
error @ workbench.desktop.main.js:sourcemap:35
error @ workbench.desktop.main.js:sourcemap:3311
Y1s @ workbench.desktop.main.js:sourcemap:1281
$logExtensionHostMessage @ workbench.desktop.main.js:sourcemap:1281
S @ workbench.desktop.main.js:sourcemap:3348
Q @ workbench.desktop.main.js:sourcemap:3348
M @ workbench.desktop.main.js:sourcemap:3348
L @ workbench.desktop.main.js:sourcemap:3348
(anonymous) @ workbench.desktop.main.js:sourcemap:3348
B @ workbench.desktop.main.js:sourcemap:29
fire @ workbench.desktop.main.js:sourcemap:29
fire @ workbench.desktop.main.js:sourcemap:1302
l.onmessage @ workbench.desktop.main.js:sourcemap:3359
workbench.desktop.main.js:sourcemap:1281 [Extension Host] Error handling webview message: {
  "msg": {
    "messageId": "8b4a03ba-8d2d-46ee-9078-f0f6641ad1bf",
    "messageType": "llm/streamChat",
    "data": {
      "completionOptions": {},
      "title": "LLaMA 3 (OpenRouter)",
      "messages": [
        {
          "role": "system",
          "content": "<important_rules>\n  You are in chat mode.\n\n  If the user asks to make changes to files offer that they can use the Apply Button on the code block, or switch to Agent Mode to make the suggested updates automatically.\n  If needed consisely explain to the user they can switch to agent mode using the Mode Selector dropdown and provide no other details.\n\n  Always include the language and file name in the info string when you write code blocks.\n  If you are editing \"src/main.py\" for example, your code block should start with ' src/main.py'\n\n  When addressing code modification requests, present a concise code snippet that\n  emphasizes only the necessary changes and uses abbreviated placeholders for\n  unmodified sections. For example:\n\n   /path/to/file\n  // ... existing code ...\n\n  {{ modified code here }}\n\n  // ... existing code ...\n\n  {{ another modification }}\n\n  // ... rest of code ...\n  \n\n  In existing files, you should always restate the function or class that the snippet belongs to:\n\n   /path/to/file\n  // ... existing code ...\n\n  function exampleFunction() {\n    // ... existing code ...\n\n    {{ modified code here }}\n\n    // ... rest of function ...\n  }\n\n  // ... rest of code ...\n  \n\n  Since users have access to their complete file, they prefer reading only the\n  relevant modifications. It's perfectly acceptable to omit unmodified portions\n  at the beginning, middle, or end of files using these \"lazy\" comments. Only\n  provide the complete file when explicitly requested. Include a concise explanation\n  of changes unless the user specifically asks for code only.\n\n</important_rules>"
        },
        {
          "role": "user",
          "content": [
            {
              "type": "text",
              "text": "hi"
            }
          ]
        },
        {
          "role": "assistant",
          "content": ""
        }
      ]
    }
  }
}

Error: HTTP 401 Unauthorized from https://openrouter.ai/api/v1/chat/completions

{"error":{"message":"No auth credentials found","code":401}}
J1s @ workbench.desktop.main.js:sourcemap:1281
$logExtensionHostMessage @ workbench.desktop.main.js:sourcemap:1281
S @ workbench.desktop.main.js:sourcemap:3348
Q @ workbench.desktop.main.js:sourcemap:3348
M @ workbench.desktop.main.js:sourcemap:3348
L @ workbench.desktop.main.js:sourcemap:3348
(anonymous) @ workbench.desktop.main.js:sourcemap:3348
B @ workbench.desktop.main.js:sourcemap:29
fire @ workbench.desktop.main.js:sourcemap:29
fire @ workbench.desktop.main.js:sourcemap:1302
l.onmessage @ workbench.desktop.main.js:sourcemap:3359
index.js:1508 Object
index.js:1508 Object

Metadata

Metadata

Labels

area:configurationRelates to configuration optionsgood-first-issueSuggested issue for new contributorside:vscodeRelates specifically to VS Code extensionkind:bugIndicates an unexpected problem or unintended behavioros:windowsHappening specifically on Windows

Type

No type

Projects

Status

Todo

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions