Repository navigation
Replies: 23 comments
|
The 403 means the key you exported is scoped to a set of connections that doesn't include the ones you added. In if (allowedConnections && allowedConnections.length > 0) {
allConnections = allConnections.filter((conn) => allowedConnections.includes(conn.id));
}
const blockedByKeyPolicyCount = connectionsBeforeKeyPolicy - allConnections.length;When that leaves nothing, Fix it in the dashboard: open API Manager, edit |
|
@charleech The answer above from @TanbirRamim is right, and I checked it against the code: the 403 is the key's connection allowlist. When a key has What I can't tell you is why a fresh install's key had an allowlist at all. The dashboard's key creation lets you choose connections, but I didn't find where a default list would be filled in for you. If you didn't pick any, tell me how you created the key (the onboarding wizard, API Manager, or the CLI) and what Allowed Connections shows for it in API Manager. That would show whether a default was applied. The fix is the one given above: edit the key and clear the allowlist (or tick the opencode connections), or use a key with no connection restriction. A second point from your log: OpenCode Free's |
|
Hi @TanbirRamim and @diegosouzapw Thank you for your advice and for pointing me to the configuration. I created the OmniRoute API key via the console by following these steps: OMNIPROXY > API Keys > Create API Key In the Create API Key screen, Management Access is set to Then I clicked Edit Permissions at the end of the row of the created API key.
At this point, I understood that all free providers are allowed by default, but the server still gave me the However, I followed your guidance by changing Allowed Connections from All Connections to Only Selected Connections and selected all five free providers: AI Horde, Cloudflare AI Playground, DuckDuckGo AI Chat, OpenCode Free, and Unclose AI. After saving the changes, I used Claude CLI to connect to OmniRoute with Previously, with a clean OmniRoute Docker installation using the Could you please advise if I am doing anything incorrectly or if there is any additional configuration I need to apply? Thank you very much for your help and support in advance. |
|
@charleech Thanks for the detail, it contradicts something I told you, so first a correction. I said the 403 comes from the key's connection allowlist, and I confirmed that against the code. But that message can only be produced when the key's The new 503,
I can't tell from here whether 3.8.51 behaves differently from your 3.8.50-web install for the same setup, so I won't call it a regression yet. Three things would settle it:
|
|
@charleech A follow-up on my own theory, so you don't spend time on it. I suspected that OpenCode Free's refusal pause could produce the misleading "excluded by this API key's connection allowlist" 403 on an unrestricted key: a combo pins keyless targets to the internal The data that would settle it is the same as before: the |
|
Thank you very much for your advice, and especially for the time you have spent investigating this issue. I really appreciate it. I would like to provide the following steps to reproduce the issue. First Round
Second Round
Please note that the log in Additional InformationFor the please refer to the attachment I hope this information is helpful for reproducing and investigating the issue. If you have any questions, need additional information, or would like me to test anything else on my side using a fresh and clean installation, please do not hesitate to let me know. Again, thank you very much for your attention to this issue, and especially for the time and effort you have spent investigating it. I really appreciate it. |
|
@charleech Thank you, this is exactly the data I needed, and it changes the picture. What your logs show, which I'm confident about because it's in the text:
What I still don't know is why the allowlist that reached the credential check wasn't empty. I tried to reproduce it in a test (a keyless pin, a real opencode row, an allowlist of null, empty, or Two questions that would help narrow it down:
|
|
I would like to provide the testing steps as follows.
curl $OMNIROUTE_URL/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OMNIROUTE_API_KEY" \
-d '{
"model": "auto/claude-opus",
"messages": [
{
"role": "user",
"content": "Explain how OmniRoute works."
}
]
}'The failure still occurred. Please refer to the attachment
curl $OMNIROUTE_URL/v1/chat/completions \
-H "Content-Type: application/json" \
-H "X-API-KEY: $ANTHROPIC_API_KEY" \
-d '{
"model": "auto/claude-opus",
"messages": [
{
"role": "user",
"content": "Explain how OmniRoute works."
}
]
}'The failure still occurred. Please refer to the attachment Please note that the log file accumulates output from all steps. I hope this information is helpful in reproducing and investigating the issue. If you have any questions, need additional information, or would like me to test anything else on my side using a fresh and clean installation, please do not hesitate to let me know. Again, thank you very much for your attention to this issue, and especially for the time and effort you have spent investigating it. I really appreciate it. |
|
@charleech Thank you for the four runs. I read the 1. This time there is no 403 anywhere. All 29 requests across the four steps end in 2. Your API key is not the cause. In step 3 (the 3. While the real connection existed (step 1), 9 of the 10 targets were rejected with 4. After you deleted the connection (steps 2–4), all 10 targets were rejected with
I'm not going to guess further without those. #15889 already tracks the missing log lines for this exact situation. |
|
Thank you for your advice. I have no idea what I'm doing wrong, so I went back to the basics and followed the steps below. Round 1OmniRoute
docker run -d \
--name omniroute \
--restart unless-stopped \
-p 20128:20128 \
--network ai-tier \
--env APP_LOG_LEVEL=debug \
diegosouzapw/omniroute:3.8.51-web
Client
docker run -it --rm \
--name omiroute-client \
--network ai-tier \
--entrypoint /bin/bash \
node:26
curl -fsSL https://claude.ai/install.sh | bash
export OMNIROUTE_API_KEY="sk-...."
export OMNIROUTE_URL="http://omniroute:20128"
export ANTHROPIC_BASE_URL=$OMNIROUTE_URL
export ANTHROPIC_API_KEY=$OMNIROUTE_API_KEY
export CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY="1"
curl -X GET \
-H "Authorization: Bearer $OMNIROUTE_API_KEY" \
http://omniroute:20128/api/v1/auto-combo/claude-opus/candidates \
| jq .
Round 2OmniRoute
Client
curl -X GET \
-H "Authorization: Bearer $OMNIROUTE_API_KEY" \
http://omniroute:20128/api/v1/auto-combo/claude-opus/candidates \
| jq .
Round 3OmniRoute
Client
curl -X GET \
-H "Authorization: Bearer $OMNIROUTE_API_KEY" \
http://omniroute:20128/api/v1/auto-combo/claude-opus/candidates \
| jq .
Please note that the log file accumulates output from all steps. I hope this information is helpful in reproducing and investigating the issue. If you have any questions, need additional information, or would like me to test anything else on my side using a fresh and clean installation, please do not hesitate to let me know. |
|
@charleech Thank you, the debug-level logs help a lot. I read the six 1. The 403 comes from the combo's own pin, not from your key. The debug line on the first request is 2. In round 3 that connection was still there. After you removed the OpenCode Free connection, the debug line is still 3. What I can't explain yet: with the keyless pin, the credential check should hand back the keyless connection. I tried it with the connection types I could think of (an OpenCode API-key account, an OpenCode Zen account, an OpenCode Go account) and with an empty, missing and Two things would settle it:
There's also a separate real defect I found from your earlier logs: a one-model sync from the OpenCode account made the other free models get rejected as "not in the live catalog". That fix is in draft PR #16042. |
|
Please find attached the screenshots for Rounds 1, 2, and 3, respectively. If you have any questions, need additional information, or would like me to perform any further tests on my side using a fresh, clean installation, please do not hesitate to let me know. |
|
@charleech Thank you for the screenshots. They show something I couldn't see in the logs, so here is what I read in them (nothing else):
Could you check these two things on the throwaway install?
I still can't reproduce the 403 myself, so this narrows where to look rather than naming a cause. |
|
@diegosouzapw Thank you for your response and advice. The Additionally, I performed a fourth test case using the following steps:
Surprisingly, the request succeeded and returned a list of candidates. I would have expected it to fail because no connections had been configured. I'm not sure whether this is a useful test scenario, but I thought the result might provide another clue for investigating the issue. Please refer to If you have any questions, need additional information, or would like me to run any further tests using a fresh, clean installation, please don't hesitate to let me know. |
|
I performed a fifth test case using the following steps:
Surprisingly, the request succeeded and returned a list of candidates. I would have expected it to fail because no connections had been configured, just as in the fourth test case. One possibility is that there may be an issue with how OmniRoute initializes its data during the first run. However, I cannot confirm this yet. For reference, I am using the following Docker image: docker image ls -a --format table | grep omniroute
diegosouzapw/omniroute 3.8.51-web 3af8a15d2086 2 weeks ago 2.36GBI hope this additional information helps narrow down the cause of the issue. If you have any questions, need additional information, or would like me to run any further tests using a fresh, clean installation, please don't hesitate to let me know. |
|
@charleech Thank you for the fifth test. What it tells me:
I then tried the exact same row (type One question would tell us whether that wizard row is what matters: on the install where you skipped the wizard, does the actual Claude CLI request (the |
|
@diegosouzapw Thank you for your response and guidance. In the fifth test, I skipped the setup wizard and sent "Hello" to auto/claude-opus via Claude CLI, but it failed with: Please refer to the screenshots and logs in the attached step-05.zip. I hope this helps narrow down the issue. I'm happy to run further tests on a fresh installation if needed. |
|
@charleech Thank you, this fifth test is the most useful one so far, and it also corrects what I asked you: the wizard row is not the trigger. What the new log shows: on a clean install with no connections at all ( That is not what I get when I run the same lookup in tests on the v3.8.51 code and on the development line: with zero connections and the same keyless pin, I get the keyless connection back every time. So something in your environment makes it return nothing, and the log doesn't say what. Three quick checks, in this order, would narrow it a lot:
I'm not guessing a cause yet. The missing log line for exactly this case is #15889. |
|
Thank you for your response and guidance. I am currently using Case 1: Skipping the Onboarding Wizard
Case 2: Using OpenCode's Free Tier
Screenshots and Configuration
Case 4: Testing with a Fresh Installation and the Onboarding Wizard
SummaryBased on my testing, both I hope this additional information helps narrow down the root cause of the issue. If you have any questions, need further information, or would like me to run additional tests using a fresh installation, please don't hesitate to let me know. Thank you again for your time and assistance. |
|
@charleech Thank you for the four cases. They make the picture a lot sharper. What I take from them (logs and text only; I did not open the screenshots of the settings pages):
What I can't explain: I ran the combo's own lookup path (including the quota-preflight wrapper and a session key) with zero connections on the v3.8.51 tag and on the development line, and I always get the keyless connection back. So I still can't reproduce the empty result. Since everything else is identical, could you tell us how the container is started: the full For the 503 specifically, #16042 (merged into the 3.8.52 line) fixed a different problem (a partial OpenCode account sync hiding the free models), so don't expect it to change this one. |
|
@diegosouzapw Thank you for your response and guidance. As I mentioned in this discussion thread (#15540), I tested this using a fresh OmniRoute Docker container with a clean configuration. The setup is straightforward, with no special configuration, as described below. OmniRoute1. Start a fresh OmniRoute Docker container docker run -d \
--name omniroute \
--restart unless-stopped \
-p 20128:20128 \
--network ai-tier \
--env APP_LOG_LEVEL=debug \
diegosouzapw/omniroute:3.8.51-web2. Complete the initial setup Access the OmniRoute console and complete the setup wizard, selecting only OpenCode Free as the provider. 3. Create an API key Create an API key using all default settings. Client1. Start a separate, fresh Docker container to simulate the client environment docker run -it --rm \
--name omniroute-client \
--network ai-tier \
--entrypoint /bin/bash \
node:262. Install Claude CLI inside the client container curl -fsSL https://claude.ai/install.sh | bash3. Set the required environment variables export OMNIROUTE_API_KEY="sk-..."
export OMNIROUTE_URL="http://omniroute:20128"
export ANTHROPIC_BASE_URL="$OMNIROUTE_URL"
export ANTHROPIC_API_KEY="$OMNIROUTE_API_KEY"
export CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY="1"4. Run Claude CLI Launch Claude CLI and select CleanupAfter completing the test, I stop the OmniRoute container and clean up unused Docker resources. docker stop omniroute
docker container prune
docker volume pruneI hope this additional information helps narrow down the root cause of the issue. If you have any questions, need further information, or would like me to run additional tests using a fresh installation, please don't hesitate to let me know. Thank you again for your time and assistance. |
|
@charleech Thank you for all the testing, it was a lot of work. An update that changes the picture: v3.8.52 was published on 2026-10-19 (npm What this means for this thread, as I read the code and that doc: on 3.8.52 the |
|
Thank you for your response and guidance. I have updated the image to
In my opinion, version Please note that I have also attached Thank you again for your time and assistance. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
I'm using a clean OmniRoute Docker installation with the image diegosouzapw/omniroute:3.8.51-web.
I created an OmniRoute API through the console and configured my client as follows:
Additionally, I only configured the free providers, following the setup instructions provided by the OmniRoute Console when I logged in for the first time. I did not configure any paid providers or additional connections.
Using
Claude CLIversion2.1.289, I selected the modelauto/claude-opusand sent a simple "Hello" message. However, the system returned the following error:{"level":40,"time":"2026-10-05T03:26:52.270Z","service":"omniroute","module":"sse","tag":"AUTH","msg":"opencode | 1 connection(s) hidden by the API key's allowed_connections/quota scope"} {"level":30,"time":"2026-10-05T03:26:52.271Z","service":"omniroute","module":"sse","tag":"COMBO","msg":"Trying model 10/10: oc/nemotron-3-ultra-free"} {"level":30,"time":"2026-10-05T03:26:52.273Z","service":"omniroute","module":"sse","tag":"ROUTING","msg":"oc/nemotron-3-ultra-free → opencode/nemotron-3-ultra-free"} {"level":40,"time":"2026-10-05T03:26:52.276Z","service":"omniroute","module":"sse","tag":"AUTH","msg":"opencode | 1 connection(s) hidden by the API key's allowed_connections/quota scope"} {"level":40,"time":"2026-10-05T03:26:52.276Z","service":"omniroute","module":"sse","tag":"AUTH","msg":"[opencode] 1 connection(s) exist but are excluded by this API key's connection allowlist / quota scope — add them to the key in the dashboard, or use a key without that scope"} {"level":40,"time":"2026-10-05T03:26:52.289Z","service":"omniroute","module":"sse","tag":"COMBO","status":403,"errorBody":"[opencode] 1 connection(s) exist but are excluded by this API key's connection allowlist / quota scope — add them to the key in the dashboard, or use a key without that scope","msg":"Model oc/nemotron-3-ultra-free failed, trying next"} {"level":40,"time":"2026-10-05T03:26:52.289Z","service":"omniroute","module":"sse","tag":"COMBO","msg":"All models failed | oc/muse-spark-1.3: auth — [opencode] 1 connection(s) exist but are excluded by this API key's connection allowlist / quota scope — add them to the key in the dashboard, or use a key without that scope (HTTP 403); oc/big-pickle: auth — [opencode] 1 connection(s) exist but are excluded by this API key's connection allowlist / quota scope — add them to the key in the dashboard, or use a key without that scope (HTTP 403); oc/muse-spark-1.2-contributor-free: auth — [opencode] 1 connection(s) exist but are excluded by this API key's connection allowlist / quota scope — add them to the key in the dashboard, or use a key without that scope (HTTP 403); oc/muse-spark-1.2: auth — [opencode] 1 connection(s) exist but are excluded by this API key's connection allowlist / quota scope — add them to the key in the dashboard, or use a key without that scope (HTTP 403); oc/muse-spark-1.3-contributor-free: auth — [opencode] 1 connection(s) exist but are excluded by this API key's connection allowlist / quota scope — add them to the key in the dashboard, or use a key without that scope (HTTP 403)... (+5 more)"} {"level":30,"time":"2026-10-05T03:26:52.343Z","service":"omniroute","module":"sse","tag":"COMBO","msg":"combo trace combo-1c59a843-5787-4f28-b563-96df41fcad4a terminal={\"status\":403,\"errorClass\":null} decisions=10"}Could you please advise if I am doing anything incorrectly or if there is any additional configuration I need to apply?
Thank you very much for your help and support in advance.
All reactions