You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
BYOK minimax_api provider cannot work with OpenAI-compatible third-party relay (X-Api-Key hardcoded) - mobile channel messages fail with 'login fail' #126
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)
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.
parseMinimaxApiConfig only accepts apiKey and baseURL — there is no way to configure a custom auth header for the upstream.
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).
In the same turn, custom_provider:minimax-2 (openai-completions, Bearer) succeeds while minimax_apifails — 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.
@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:
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 defaultx-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.
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.
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.
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.
@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.
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!
Activity
basil-k-aji-dev commentedon Sep 19, 2026
@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-headersWhat it does
Gives
minimax_apitheheadersescape hatchcustom_provideralready has, rather than inventing a separate auth-mode vocabulary for one provider:MinimaxApiConfig.headers, parsed by aparseProviderHeadersthat 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.resolveMinimaxTestTarget.ModelConnectionTestTarget.headersalready existed; the MiniMax path simply never populated it.base_urlandapi_keyalready follow, asprovider-views.tsstates.headerNamesonly, 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
buildProviderHeadersdrops its defaultx-api-keywhen the caller suppliesauthorization, 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.tsfailed, 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 errorsvitest run packages/local-runtime-v2/src/service/model-system/ packages/config/— 488 passed, 1 skippedtest/vitest-suites.jsonrather than a config file, per AGENTS.mdsrc/, which is the claim they exist to makeNot 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
capabilitysuite 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.hetaoBackend commentedon Sep 19, 2026
I confirmed the missing
minimax_api.headerspath 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 configuredx-api-keyis 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 verifygates 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.
fix: honor MiniMax API custom authentication headers
yujiachen-y commentedon Sep 19, 2026
Hi @tim-korso , thanks for analysis and discussion. I thought that issue for a while.
We won't make
minimax_apiheader-configurable: it's the official endpoint and no product surface ever writes itsbaseURL. Third-parity BYOK should belong tocustom_provider, which already supports custom headers and Bearer auth.cc @hetaoBackend @SaladDay and @basil-k-aji-dev for #195
basil-k-aji-dev commentedon Sep 19, 2026
@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_providerpointed at the relay withAuthorization: Bearersucceeded whileminimax_apifailed. 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_apiorMINIMAX_API_PROVIDER_IDreference anywhere underpackages/local-runtime/src/channels/, andprimary-agent-session-model-repair.tsresolves throughresolveModelAvailabilityfrom@mavis/config— the shared path. So acustom_providermodel 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:
That sentence describes the transport and not the decision. It is emitted when
minimax_apihas 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 namecustom_provideras 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_provideranswer. 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.
hetaoBackend commentedon Oct 19, 2026
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。感谢反馈!