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
OpenAI-compatible chat providers fail when the endpoint requires max_completion_tokens instead of max_tokens #45223
The generic OpenAI-compatible chat protocol (packages/llm/src/protocols/openai-chat.ts) always sends max_tokens in the request body. Some OpenAI-compatible deployments reject this and require max_completion_tokens instead, returning a standard error like:
{
"error": {
"message": "Unsupported parameter: 'max_tokens' is not supported with this model. Use 'max_completion_tokens' instead.",
"type": "invalid_request_error",
"param": "max_tokens",
"code": "unsupported_parameter"
}
}
Right now this makes the provider unusable out of the box — the only workaround is writing a custom plugin that intercepts chat.params and rewrites the field manually.
This isn't a one-off case: OpenCode already ships two provider-specific patches for the same underlying issue (Cerebras: packages/core/src/plugin/provider/cerebras.ts, Snowflake Cortex: packages/core/src/plugin/provider/snowflake-cortex.ts, both rewriting max_tokens → max_completion_tokens). Those are hardcoded to specific npm packages / provider IDs, so they don't help anyone using a custom openai-compatible provider pointed at a gateway with this same requirement.
Plugins
None required for this fix — it replaces the need for a custom chat.params plugin.
OpenCode version
1.18.23
Steps to reproduce
Configure a custom provider using @ai-sdk/openai-compatible pointed at any OpenAI-compatible endpoint that rejects max_tokens and requires max_completion_tokens.
Send a chat request through that provider.
Request fails instead of retrying with the corrected field.
If your issue is distinct (e.g. it specifically affects custom openai-compatible gateway configs rather than named providers), please clarify what makes it different from the above.
The duplicate check — this overlaps with #25096, #32776, #40885, #22623 on symptom (all are max_tokens vs max_completion_tokens), but those are scoped to specific providers/model families (Azure, cloudflare-ai-gateway, gpt-5.x by name). This report is about the general case: any @ai-sdk/openai-compatible provider pointed at a gateway that requires max_completion_tokens, regardless of model name or which gateway it is. Happy to have this closed in favor of one of those if maintainers prefer to track it there instead.
Dug into this a bit more before proposing a fix, since I initially assumed there was one request path — there are actually two:
Native runtime (packages/llm, opt-in via experimentalNativeLlm) — not the default, most users won't hit this.
AI SDK runtime (default) — calls streamText() from Vercel's ai package, which builds the request via @ai-sdk/openai-compatible directly. This is the path everyone in the linked issues is actually hitting, and it always sends max_tokens with no way to configure otherwise.
Two things ruled out:
A blanket rewrite to max_completion_tokens for all openai-compatible providers — unsafe, since plenty of self-hosted OpenAI-compatible servers only accept max_tokens and would break.
Matching on model name (e.g. gpt-5*) — works today but is brittle for future model families and doesn't help custom-named providers behind a gateway (like this report).
Proposed fix: an explicit, opt-in compatibility flag on the model config, e.g.
honored by the default request-prep path before streamText is called. This isn't a new concept — packages/llm/src/schema/options.ts already has ModelCompatibility with a toolSchema field for this exact kind of "known upstream quirk," just currently scoped to the native runtime only. This would widen that pattern to the default path and add the token-field case.
Implementation-wise, this doesn't need new plugin API either — @ai-sdk/openai-compatible already lets provider options pass through for any key it doesn't recognize as standard, which is the same mechanism the existing Cerebras/Snowflake Cortex plugins use to do this rewrite today. This would just be that same technique, driven by the config flag instead of a hardcoded provider check.
Hey @neriousy — saw you got assigned. Have a fix ready on my end for the design I proposed above (opt-in compatibility.max_tokens_field on model config). Should I open the PR, or are you already working on something for this?
Another variant of this issue: the Responses API has renamed the parameter again from max_completion_tokens to max_output_tokens. OpenCode 1.18.32+ sends max_completion_tokens but newer endpoints implementing the latest spec reject it with:
400 Unsupported parameter: 'max_completion_tokens'.
In the Responses API, this parameter has moved to 'max_output_tokens'.
This affects any custom openai-compatible provider pointed at an endpoint that implements the newest Responses API spec. The provider needs to send max_output_tokens instead.
Endpoint: custom gateway implementing the latest Responses API
The fix should handle all three parameter names (max_tokens, max_completion_tokens, max_output_tokens) with automatic fallback when the API rejects the parameter.
Activity
github-actions commentedon Aug 26, 2026
This issue might be a duplicate of existing issues. Please check:
max_tokensrejected, requiresmax_completion_tokensinsteadmax_tokensto models that requiremax_completion_tokensmax_tokenson AI SDK fallback pathmax_tokensvsmax_completion_tokens; per-model compat not honoredmax_tokensparameter not supported, needmax_completion_tokensinsteadIf your issue is distinct (e.g. it specifically affects custom
openai-compatiblegateway configs rather than named providers), please clarify what makes it different from the above.VarunMotiyani commentedon Aug 26, 2026
The duplicate check — this overlaps with #25096, #32776, #40885, #22623 on symptom (all are
max_tokensvsmax_completion_tokens), but those are scoped to specific providers/model families (Azure, cloudflare-ai-gateway, gpt-5.x by name). This report is about the general case: any@ai-sdk/openai-compatibleprovider pointed at a gateway that requiresmax_completion_tokens, regardless of model name or which gateway it is. Happy to have this closed in favor of one of those if maintainers prefer to track it there instead.Dug into this a bit more before proposing a fix, since I initially assumed there was one request path — there are actually two:
packages/llm, opt-in viaexperimentalNativeLlm) — not the default, most users won't hit this.streamText()from Vercel'saipackage, which builds the request via@ai-sdk/openai-compatibledirectly. This is the path everyone in the linked issues is actually hitting, and it always sendsmax_tokenswith no way to configure otherwise.Two things ruled out:
max_completion_tokensfor allopenai-compatibleproviders — unsafe, since plenty of self-hosted OpenAI-compatible servers only acceptmax_tokensand would break.gpt-5*) — works today but is brittle for future model families and doesn't help custom-named providers behind a gateway (like this report).Proposed fix: an explicit, opt-in compatibility flag on the model config, e.g.
honored by the default request-prep path before
streamTextis called. This isn't a new concept —packages/llm/src/schema/options.tsalready hasModelCompatibilitywith atoolSchemafield for this exact kind of "known upstream quirk," just currently scoped to the native runtime only. This would widen that pattern to the default path and add the token-field case.Implementation-wise, this doesn't need new plugin API either — @ai-sdk/openai-compatible already lets provider options pass through for any key it doesn't recognize as standard, which is the same mechanism the existing Cerebras/Snowflake Cortex plugins use to do this rewrite today. This would just be that same technique, driven by the config flag instead of a hardcoded provider check.
VarunMotiyani commentedon Aug 26, 2026
Hey @neriousy — saw you got assigned. Have a fix ready on my end for the design I proposed above (opt-in compatibility.max_tokens_field on model config). Should I open the PR, or are you already working on something for this?
fix(sandbox-runner): use OpenAI's own SDK for OpenAI runs, and bump o…
throny commentedon Sep 29, 2026
Another variant of this issue: the Responses API has renamed the parameter again from
max_completion_tokenstomax_output_tokens. OpenCode 1.18.32+ sendsmax_completion_tokensbut newer endpoints implementing the latest spec reject it with:This affects any custom
openai-compatibleprovider pointed at an endpoint that implements the newest Responses API spec. The provider needs to sendmax_output_tokensinstead.Config used:
@opencode/ai/providers/openai-compatiblegpt-6-luna(reasoning model)The fix should handle all three parameter names (
max_tokens,max_completion_tokens,max_output_tokens) with automatic fallback when the API rejects the parameter.thdxr commentedon Oct 11, 2026
Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (
opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊