Skip to content

BYOK minimax_api provider cannot work with OpenAI-compatible third-party relay (X-Api-Key hardcoded) - mobile channel messages fail with 'login fail' #126

Closed as not planned

Description

@tim-korso

Environment

  • MiniMax Code 3.0.60, macOS
  • minimaxModelSource: minimax_api_key
  • A custom provider (openai-completions + Authorization: Bearer) works fine for desktop chat and is the default model

Symptom

Messages sent from the mobile app (connected to desktop) fail with:

BYOK provider minimax_api upstream error: login fail: Please carry the API secret key in the 'X-Api-Key' field of the request header

Root cause analysis (verified against app behavior)

  1. The minimax_api provider defaults to https://api.minimaxi.com/anthropic (official endpoint). The configured minimax_api.apiKey is a key for a third-party OpenAI-compatible relay.
  2. parseMinimaxApiConfig only accepts apiKey and baseURL — there is no way to configure a custom auth header for the upstream.
  3. The SDK's apiKeyAuth sends the key as X-Api-Key header, but the relay only accepts Authorization: Bearer (verified: X-Api-Key → 401 Missing API key; Bearer → 200 OK). The relay does expose an Anthropic-compatible endpoint (/v1/messages).
  4. In the same turn, custom_provider:minimax-2 (openai-completions, Bearer) succeeds while minimax_api fails — some mobile-channel requests resolve to the unprefixed builtin MiniMax model and hit minimax_api.

Expected behavior

  • Allow minimax_api (or custom providers) to configure auth as Authorization: Bearer / authToken, so BYOK users with third-party relays can use them for the mobile channel.
  • Or: mobile-channel auxiliary requests should use the same custom_provider model as the main conversation instead of falling back to minimax_api.

Logs

~/.minimax/v2/observability/logs/runtime-2026081123.log — entries BYOK provider minimax_api upstream error: login fail: ... at 23:40 / 23:45 / 23:47

Activity

  1. basil-k-aji-dev commented on Sep 19, 2026

    @basil-k-aji-dev

    @tim-korso your root-cause analysis holds up — I worked from it directly, and all four numbered points are accurate against main (cc00e01).

    CONTRIBUTING.md accepts code only from collaborators, so I cannot open a pull request. The branch is public if a maintainer wants to take it, cherry-pick it, or ignore it:

    basil-k-aji-dev/minimax-code → fix/minimax-api-custom-auth-headers

    What it does

    Gives minimax_api the headers escape hatch custom_provider already has, rather than inventing a separate auth-mode vocabulary for one provider:

    minimax_api:
      apiKey: sk-...
      baseURL: https://relay.example.com/anthropic
      headers:
        Authorization: Bearer sk-...
    • MinimaxApiConfig.headers, parsed by a parseProviderHeaders that keeps string values only — a header reaches the wire verbatim, so a number or nested object would either throw at request time or serialize into something the endpoint never meant to receive.
    • Carried into resolveMinimaxTestTarget. ModelConnectionTestTarget.headers already existed; the MiniMax path simply never populated it.
    • Folded into the connection-test fingerprint, so editing headers retires the cached verdict instead of leaving a stale green badge — the rule base_url and api_key already follow, as provider-views.ts states.
    • The provider view reports headerNames only, never values, since a value can hold a second credential and the view is returned by the settings API.

    One thing the issue did not ask for

    buildProviderHeaders drops its default x-api-key when the caller supplies authorization, so the same secret does not travel under two schemes — a wider blast radius on any endpoint that logs headers, for no benefit.

    Only the default. I got this wrong first: an earlier draft deleted it unconditionally and discover-models.test.ts failed, because model discovery deliberately probes an unknown endpoint with both schemes. An explicit header outranks a default, and that case now has a test of its own citing why.

    Checks

    • tsc -p tsconfig.standalone.json --noEmit — 0 errors
    • vitest run packages/local-runtime-v2/src/service/model-system/ packages/config/ — 488 passed, 1 skipped
    • New tests registered in test/vitest-suites.json rather than a config file, per AGENTS.md
    • Three of them fail against unpatched src/, which is the claim they exist to make

    Not verified by me: I have no third-party relay, so the end-to-end path in your report is unconfirmed on my side. What is confirmed is that configured headers now reach the request and the key stops going out twice. The wider capability suite has failures in 11 files I did not touch (thread-goal, SQLite repositories, update-service); those fail identically with my changes stashed on a clean tree, so they look environmental here, but I could not get a green full-suite run and am not claiming one.

  2. hetaoBackend commented on Sep 19, 2026

    @hetaoBackend
    Collaborator

    I confirmed the missing minimax_api.headers path in current public source and opened #200, building on @basil-k-aji-dev's proposal in #195 and crediting this report.

    The PR sends configured headers in both connection probes and real SDK conversation requests. An explicit Authorization header suppresses the default x-api-key; an explicitly configured x-api-key is preserved. It also invalidates cached verdicts after header edits and shows header names without values. The config example is included in the PR; the relay must still support Anthropic Messages (/v1/messages).

    Validation: the new regression suite reproduced 7 failures before the fix; all 458 focused Model System tests and all 14 clean-commit pnpm verify gates passed on macOS arm64 / Node 26.4.0 (c2796f8). These are offline fixtures, including actual SDK request-header generation. A live relay, Desktop/mobile end-to-end flow, and Windows/Linux local acceptance have not been verified.

    #200 is pending review and has not shipped. It addresses the authentication-header limitation; it does not change which model mobile-channel auxiliary requests select. Leaving this issue open for that remaining scope and end-to-end confirmation.

  3. added
    bugSomething isn't working
    desktopMiniMax Code desktop app
    needs-triageAwaiting maintainer assessment
    and removed
    needs-triageAwaiting maintainer assessment
    desktopMiniMax Code desktop app
    on Sep 19, 2026
  4. yujiachen-y commented on Sep 19, 2026

    @yujiachen-y
    Collaborator

    Hi @tim-korso , thanks for analysis and discussion. I thought that issue for a while.

    We won't make minimax_api header-configurable: it's the official endpoint and no product surface ever writes its baseURL. Third-parity BYOK should belong to custom_provider, which already supports custom headers and Bearer auth.

    cc @hetaoBackend @SaladDay and @basil-k-aji-dev for #195

  5. basil-k-aji-dev commented on Sep 19, 2026

    @basil-k-aji-dev

    @yujiachen-y understood, and I think the decision is right. Two pieces of evidence from this thread support it rather than contradict it.

    The reporter's own comparison already contains the workaround. From @tim-korso's report, in the same session, a custom_provider pointed at the relay with Authorization: Bearer succeeded while minimax_api failed. So the capability was never missing from the product — only from the provider that is not meant to carry it.

    The mobile-channel half of this issue also looks covered. I checked whether channels pin the provider, since that was the part @hetaoBackend flagged as outside #200's scope: there is no minimax_api or MINIMAX_API_PROVIDER_ID reference anywhere under packages/local-runtime/src/channels/, and primary-agent-session-model-repair.ts resolves through resolveModelAvailability from @mavis/config — the shared path. So a custom_provider model should be reachable from a channel the same way it is from the desktop surface. Worth someone with a relay confirming end to end, since I do not have one.

    If that holds, the remaining gap in #126 is not code but discoverability. What a user hits today is:

    login fail: Please carry the API secret key in the 'X-Api-Key' field
    

    That sentence describes the transport and not the decision. It is emitted when minimax_api has been pointed at something that is not the official endpoint, which is exactly the case you have now defined as unsupported — so it is in a good position to say so, and to name custom_provider as the supported route. The same line in the BYOK documentation would probably prevent the next report.

    I am happy to open that as a separate docs/error-message issue if it is useful, and equally happy to leave it if you would rather close #126 with the custom_provider answer. Either way I will not pursue the header change.

    On #195: I opened that access request specifically to contribute this fix, and the fix is not wanted, so the request has no purpose left. Closing it. Thank you both for the time spent reviewing a change you were always going to decline on design grounds — @hetaoBackend's review in particular found a real defect in my branch that I would otherwise have carried forward.

  6. hetaoBackend commented on Oct 19, 2026

    @hetaoBackend
    Collaborator

    Closing as part of a backlog cleanup: this issue was filed more than a month ago against an older release, and the codebase has changed substantially since then. If it still reproduces on the latest version, please open a new issue with the current version and reproduction steps. Thank you for the report!

    批量清理积压:该 issue 创建已超过一个月,针对的是较旧版本,代码已有较大变化。如果在最新版本上仍能复现,欢迎附上当前版本号和复现步骤重新提交 issue。感谢反馈!

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdesktopMiniMax Code desktop appneeds-triageAwaiting maintainer assessment

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions