Skip to content

Custom @ai-sdk/google provider loads correctly but drops API key at runtime when using custom baseURL #21738

Closed as not planned

Description

@tpwcnls

Bug: Custom @ai-sdk/google provider loads correctly but drops API key at runtime when using custom baseURL

Summary

On OpenCode 1.4.2 on Windows, a custom Gemini native provider can be discovered correctly from opencode.json, and its model can be selected successfully.

However, when the model is actually executed, the runtime request fails with:

401 invalid_request_error: You didn't provide an API key. You need to provide your API key in an Authorization header using Bearer auth

In the same environment, with the same API key, the same project, and the same Gemini model, switching only the provider implementation to @ai-sdk/openai-compatible succeeds immediately and returns OK.

This strongly suggests a runtime auth propagation issue in OpenCode's handling of custom native Google/Gemini providers, rather than a config parsing issue.

Environment

  • OpenCode: 1.4.2
  • OS: Windows
  • Entry point: opencode-cli.exe run --print-logs
  • Proxy service: ofox.ai

Minimal Reproduction Config

{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "ofox-google-native": {
      "npm": "@ai-sdk/google",
      "name": "Ofox Google Native",
      "options": {
        "baseURL": "https://api.ofox.ai/gemini",
        "apiKey": "{file:C:/Users/Roger/.config/opencode/.secrets/ofox-api-key}"
      },
      "models": {
        "gemini-3.1-flash-lite-preview": {
          "name": "Gemini 3.1 Flash Lite"
        }
      }
    },
    "ofox-openai-check": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Ofox OpenAI Check",
      "options": {
        "baseURL": "https://api.ofox.ai/v1",
        "apiKey": "{file:C:/Users/Roger/.config/opencode/.secrets/ofox-api-key}"
      },
      "models": {
        "google/gemini-3.1-flash-lite-preview": {
          "name": "Gemini 3.1 Flash Lite"
        }
      }
    }
  }
}

Reproduction Steps

Set the environment:

$env:HOME='F:\Project\AIBuilder\OpenCodeTest\.tmphome'
$env:USERPROFILE='F:\Project\AIBuilder\OpenCodeTest\.tmphome'

Then run:

Set-Location 'F:\Project\AIBuilder\OpenCodeTest\temp_gemini_report'
& 'C:\Users\Roger\AppData\Local\opencode\opencode-cli.exe' run --model ofox-google-native/gemini-3.1-flash-lite-preview --print-logs 'Reply with OK only.'

Expected Behavior

The configured options.apiKey should be propagated into the final request, and the request should authenticate successfully against the custom Gemini-compatible endpoint.

Actual Behavior

The provider and model are discovered successfully, but the runtime request fails with:

You didn't provide an API key. You need to provide your API key in an Authorization header using Bearer auth

Evidence

The following log lines show that:

  1. the custom provider is discovered,
  2. OpenCode actually uses the bundled @ai-sdk/google provider path,
  3. the final request returns 401 with a missing API key error.
INFO  service=provider providerID=ofox-google-native found
INFO  service=llm providerID=ofox-google-native modelID=gemini-3.1-flash-lite-preview ...
INFO  service=provider providerID=ofox-google-native pkg=@ai-sdk/google using bundled provider
...
"statusCode":401
"responseBody":"{\"error\":{\"message\":\"You didn't provide an API key. You need to provide your API key in an Authorization header using Bearer auth (i.e. Authorization: Bearer YOUR_KEY).\",\"type\":\"invalid_request_error\",\"code\":401}}"
ERROR service=session.processor error=Unauthorized

Failure tail:

"statusCode":401
"responseBody":"{\"error\":{\"message\":\"You didn't provide an API key. You need to provide your API key in an Authorization header using Bearer auth (i.e. Authorization: Bearer YOUR_KEY).\",\"type\":\"invalid_request_error\",\"code\":401}}"
ERROR  service=session.processor error=Unauthorized stack=AI_APICallError: Unauthorized
Error: Unauthorized: {"error":{"message":"You didn't provide an API key. You need to provide your API key in an Authorization header using Bearer auth (i.e. Authorization: Bearer YOUR_KEY).","type":"invalid_request_error","code":401}}

Control Experiment

Using the same key, same environment, same Gemini model, and same prompt, but switching only the provider implementation to @ai-sdk/openai-compatible:

Set-Location 'F:\Project\AIBuilder\OpenCodeTest\temp_gemini_report'
& 'C:\Users\Roger\AppData\Local\opencode\opencode-cli.exe' run --model ofox-openai-check/google/gemini-3.1-flash-lite-preview --print-logs 'Reply with OK only.'

Result:

OK

Successful tail:

OK
INFO  service=state key=F:\Project\AIBuilder\OpenCodeTest\temp_gemini_report state disposal completed
INFO  service=server event disconnected

What This Rules Out

This control experiment rules out:

  • invalid API key
  • unavailable Gemini model
  • broken project directory or HOME setup
  • config file not being loaded
  • Ofox service being completely unavailable

Conclusion

This does not look like a config discovery problem. It looks like a runtime auth propagation problem in OpenCode's handling of custom native Google/Gemini providers.

More specifically, the evidence supports the following:

  • the custom provider is discovered correctly
  • the runtime request goes through the bundled @ai-sdk/google path
  • the configured options.apiKey does not make it into the final request correctly

Suspected Investigation Areas

  • whether options.apiKey is dropped somewhere between config resolution and request creation
  • whether the bundled provider path still applies built-in auth behavior intended for first-party Google/Gemini setup
  • whether custom baseURL support for native providers is incomplete

Activity

  1. added
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on Apr 9, 2026
  2. tpwcnls commented on Apr 9, 2026

    @tpwcnls
    Author

    This looks closely related to #21737.

    Both issues reproduce on Windows with OpenCode 1.4.2, both involve custom native providers with a custom baseURL, and both fail at runtime with the same 401 invalid_request_error about a missing API key. The matching control experiments succeed when switching only the provider implementation to @ai-sdk/openai-compatible.

    This may indicate a shared runtime auth propagation bug affecting custom native provider handling.

  3. tpwcnls commented on Apr 10, 2026

    @tpwcnls
    Author

    Update after further investigation:

    The earlier "runtime auth propagation" conclusion now looks incomplete.

    The root cause appears to be the proxy endpoint path, not just API key propagation.

    For Ofox native endpoints, the working base URLs need to include the protocol-specific version segment:

    • Anthropic: https://api.ofox.ai/anthropic/v1
    • Gemini: https://api.ofox.ai/gemini/v1beta

    Using incomplete paths such as:

    • https://api.ofox.ai/anthropic
    • https://api.ofox.ai/gemini

    can trigger a misleading 401 invalid_request_error saying the API key was not provided.

    So the current best understanding is:

    • OpenCode may not be the root cause here
    • the more direct cause is that the native proxy baseURL must include the correct versioned path
    • otherwise the request hits the wrong proxy route and returns a misleading auth error

    Please treat my earlier auth-propagation diagnosis as provisional. The stronger current explanation is incorrect endpoint pathing for the native proxy.

  4. removed
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on May 3, 2026
  5. xflcx1991 commented on May 22, 2026

    @xflcx1991

    By capturing the network packets, I think I’ve figured out the exact reason. All that’s needed is to change the baseurl from https://api.ofox.io/gemini, as recommended by Ofox, to https://api.ofox.io/gemini/v1beta/models.

    Image

    The screenshot was taken using mitmproxy packet capture.

    Successful requests in the red box were sent from Python code, using the google-genai package.

    from google import genai
    
    client = genai.Client(
        api_key="sk-of-xxx",
        http_options={
            "api_version": "v1beta",
            "base_url": "https://api.ofox.io/gemini",
        },
    )
    
    for chunk in client.models.generate_content_stream(
        model="google/gemini-3.5-flash",
        contents="hello",
        ):
        print(chunk.text, end="", flush=True)

    Failed requests came from the OFox service provider configured in OpenCode.

    ❯ cat opencode.json
    {
      "$schema": "https://opencode.ai/config.json",
      "provider": {
        "ofox": {
          "models": {
            "google/gemini-3.5-flash": {
              "name": "google/gemini-3.5-flash"
            }
          },
          "npm": "@ai-sdk/google",
          "options": {
            "apiKey": "sk-of-xxx",
            "baseURL": "https://api.ofox.io/gemini"
          }
        }
      }
    }
    

    The path requested by the successful request can be seen through packet capture.
    https://api.ofox.io/gemini/v1beta/models/google/gemini-3.5-flash:streamGenerateContent?alt=sse
    And the path requested by the loser is
    https://api.ofox.io/gemini/google/gemini-3.5-flash:streamGenerateContent?alt=sse

    The v1beta/models/ path was missing. By manually adding it to the baseURL in opencode.json, this issue could be resolved (the image error has nothing to do with this issue).

    Image

    So is the problem on the opencode side or the @ai-sdk/google side?

  6. larrykoo711 commented on May 22, 2026

    @larrykoo711
  7. kingpro1985 commented on May 22, 2026

    @kingpro1985
  8. github-actions commented on Jul 22, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

  9. celeste1900 commented on Oct 15, 2026

    @celeste1900

    Update from the Ofox side: both gateway behaviors described in this thread are fixed as of today (2026-10-15).

    1. Unknown paths such as https://api.ofox.ai/gemini/google/<model>:generateContent (missing v1beta) now return a 404 that names the correct base URLs (/v1, /anthropic/v1, /gemini/v1beta) instead of the misleading 401 "You didn't provide an API key".
    2. The gateway now accepts the path @ai-sdk/google builds for model ids containing a slash, i.e. /gemini/v1beta/google/gemini-3.5-flash:streamGenerateContent without the models/ segment. generateContent, streamGenerateContent and countTokens all work, and the models/ form keeps working.

    So with opencode 1.x the config below works as-is, no /models workaround needed:

    "npm": "@ai-sdk/google",
    "options": { "baseURL": "https://api.ofox.ai/gemini/v1beta" }

    opencode v2 was not affected by (2). Thanks @tpwcnls and @xflcx1991 for the packet captures that pinpointed this.

  10. celeste1900 commented on Oct 15, 2026

    @celeste1900

    @tpwcnls @xflcx1991 — your repro configs and the packet capture are what let us pin this down, so we'd like to say thanks with a small credit: $5 each on your Ofox account. Please email hi@ofox.ai with the subject "opencode #21738" and the email address of your Ofox account, and we'll apply it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions