Skip to content

[BUG] Plugin client missing Authorization header when OPENCODE_SERVER_PASSWORD is set #9706

Closed as not planned

Description

@uf-hy

Description

Description

When OPENCODE_SERVER_PASSWORD is set, the client passed to plugins via PluginInput does not include the Authorization header, causing all plugin API calls (like ctx.client.session.create()) to fail with 401 Unauthorized.

Steps to Reproduce

  1. Set environment variables:
    export OPENCODE_SERVER_PASSWORD=your-password
    export OPENCODE_SERVER_USERNAME=your-username
  2. Start opencode TUI
  3. Use any plugin tool that calls ctx.client.session.create() (e.g., oh-my-opencode's look_at tool)
  4. Observe: Error: Failed to create session: Unauthorized

Expected Behavior

The plugin client should include the Authorization header when OPENCODE_SERVER_PASSWORD is set, and plugin API calls should work normally.

Actual Behavior

Plugin API calls fail with 401 Unauthorized.

Analysis

I noticed that in packages/opencode/src/plugin/index.ts, the client is created without the Authorization header:

const client = createOpencodeClient({
  baseUrl: Server.url().href,
  // @ts-ignore - fetch type incompatibility
  fetch: async (...args) => Server.App().fetch(...args),  // <-- No auth header
})

However, in packages/opencode/src/cli/cmd/tui/worker.ts, the auth header IS correctly added:

const fetchFn = (async (input: RequestInfo | URL, init?: RequestInit) => {
  const request = new Request(input, init)
  const auth = getAuthorizationHeader()  // <-- Auth header added here
  if (auth) request.headers.set("Authorization", auth)
  return Server.App().fetch(request)
}) as typeof globalThis.fetch

It seems like the plugin client might need similar auth handling, but I'm not 100% sure if this is the correct fix approach.

Environment

  • opencode version: 1.1.27
  • OS: macOS
  • Plugin: oh-my-opencode 3.0.0-beta.11

Plugins

oh-my-opencode 3.0.0-beta.11

OpenCode version

1.1.27

Steps to reproduce

  1. Set OPENCODE_SERVER_PASSWORD
  2. Use oh-my-opencode plugin
  3. Call look_at tool
  4. Get 401 Unauthorized

Screenshot and/or share link

No response

Operating System

macos 26.0

Terminal

Terminal

Activity

  1. github-actions commented on Jan 20, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    The symptoms and root cause appear to be identical - the plugin client is missing the Authorization header when OPENCODE_SERVER_PASSWORD is set. Feel free to ignore if this addresses a specific case not covered by #8676.

  2. R44VC0RP commented on Jan 20, 2026

    @R44VC0RP
    Contributor

    Thanks for the detailed bug report and excellent analysis @uf-hy! You've correctly identified the root cause.

    This is a confirmed bug and is related to #8676 (which covers the Desktop/Tauri case). There's already an open PR #9095 that addresses TUI auth when using HTTP mode, but it doesn't fix the plugin client path you've identified in plugin/index.ts.

    Your analysis is spot-on:

    • worker.ts correctly uses getAuthorizationHeader() to add Basic Auth
    • plugin/index.ts creates the client without any auth headers

    Next Steps:
    We'll either extend PR #9095 to also fix the plugin client, or create a separate targeted fix. The fix is straightforward - using a similar fetchWithAuth wrapper like the TUI worker does.

    For now, the workaround is to not set OPENCODE_SERVER_PASSWORD when using plugins that make SDK API calls, or use the CLI without the server password when testing plugins.

    Linking this to #8676 for tracking. Thanks for the clear reproduction steps!

  3. LeonMueller-OneAndOnly commented on Jan 31, 2026

    @LeonMueller-OneAndOnly
    Contributor

    Info for maintainers: This fix for the plugin authorization issue was incorporated into the pr #9095 - which solves the auth issue when a server-password is set for the

    • plugins
    • the tui+server starting
    • and the tui attaching
  4. david-christ commented on Mar 1, 2026

    @david-christ

    As a temporary workaround when using the SDK, e.g. to write plugins, you can do this (messing with "private" methods):

      const password = process.env.OPENCODE_SERVER_PASSWORD
      if (password) {
        const username = process.env.OPENCODE_SERVER_USERNAME || "opencode"
        const authHeader = "Basic " + btoa(`${username}:${password}`)
        const innerClient = (client as any)._client
        if (innerClient?.interceptors?.request?.use) {
          innerClient.interceptors.request.use((req: Request) => {
            req.headers.set("Authorization", authHeader)
            return req
          })
        }
      }
  5. github-actions commented on May 1, 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.

  6. xarathos86 commented on Jun 5, 2026

    @xarathos86

    I'm still experiencing this issue. While adding a server from the UI, the endpoint gets something like:
    2026-06-05 14:57:40 [WARN]
    The 'Authorization' header is present but not in the expected form 'Authorization: Bearer $LM_API_TOKEN'. The provided value cannot be used.
    Apparently not replacing that with the proper token.
    Setting Bearer or not before the token doesn't change anything.

  7. joeyism commented on Sep 2, 2026

    @joeyism

    I'm also still experiencing this when using NVIDIA NIM

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions