Skip to content

models: catalog variant settings sent with camelCase keys to OpenAI-compatible providers -> 400 'Extra inputs are not permitted' #41971

Closed as not planned

Description

@ArchiTecCTT

Summary

Variant settings from the built-in model catalog are serialized into the request body with their raw camelCase keys (e.g. reasoningEffort). Strict OpenAI-compatible providers reject these as unknown fields, so selecting a standard variant (e.g. max) on models like Fireworks kimi-k3 fails with a 400 before any token is generated. The same body with the snake_case key (reasoning_effort) succeeds.

Environment

  • opencode version: 0.0.0-next-17276 (v2, next channel)
  • OS: Linux 6.17.0-1022-azure x86_64 (Ubuntu)
  • Terminal: xterm-256color
  • Shell: /usr/bin/zsh
  • Install/channel: npm @opencode-ai/cli@next, background service
  • Active plugins: @javargasm/opencode-kiro-auth, @plannotator/opencode@latest, @tarquinen/opencode-dcp, cc-safety-net@latest, envsitter-guard, oc-codex-multi-auth

Reproduction

  1. Use a fresh config with no provider overrides (stock catalog).
  2. Select a model whose catalog variants carry reasoningEffort, e.g. fireworks-ai/accounts/fireworks/models/kimi-k3 (catalog variant: {"id": "max", "settings": {"reasoningEffort": "max"}}).
  3. Send any message (e.g. via a subagent with variant: max).
  4. Observe AI.Error: AISDK.doStream: Bad Request from the session runner.

Expected Behavior

Variant settings keys are normalized before serialization (reasoningEffort → reasoning_effort, reasoningSummary → reasoning_summary), matching what OpenAI-compatible endpoints accept, so catalog variants work out of the box on strict providers.

Actual Behavior

The outgoing request contains the camelCase key verbatim. Fireworks returns:

400 invalid_request_error
"Extra inputs are not permitted, field: 'reasoningEffort', value: 'max'"

Confirmed by capturing the exact outgoing body (26 KB capture shows variant settings pass through raw; nested settings like chat_template_kwargs also arrive verbatim) and by direct API calls: identical body with reasoningEffort → 400, with reasoning_effort → 200.

Additional Context

  • No user config involved in the failure: the failing kimi-k3 model had zero config overrides; only the shipped catalog metadata was in play.
  • OpenAI/Azure/GitHub Copilot families are unaffected — that SDK path recognizes reasoningEffort/reasoningSummary and renders them correctly; the raw pass-through only surfaces on strict OpenAI-compatible endpoints.
  • Affected catalogs observed in the live model catalog (all with camelCase reasoningEffort variants): Fireworks (12 models), Together AI (7), Z.AI (1), Cloudflare Workers AI (7), Cloudflare AI Gateway (33), Hugging Face (12), opencode zen (3).
  • Workaround: per-model config overlays defining the same variants with snake_case reasoning_effort settings. This requires one overlay per affected model (63 models across 7 providers in our case) and does not remove the camelCase key from the merged catalog.
  • Frequency: consistent, not intermittent.
  • Verified on v2 next-17276; V1 behavior not verified.

Activity

  1. github-actions commented on Aug 12, 2026

    @github-actions
    Contributor

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

    If they are distinct enough to warrant separate tracking, please feel free to ignore this note.

  2. ddobrinskiy-top commented on Sep 18, 2026

    @ddobrinskiy-top

    Same root cause, different variant setting — adding a data point from the v1 stable channel (this issue was filed against v2 next).

    Repro on opencode 1.18.31 (stable)

    1. Stock catalog, authenticated fireworks-ai provider, no per-model config overrides.
    2. In the TUI model picker, select the Priority service-tier variant of a Fireworks model.
    3. Send any message.

    Fireworks rejects the request with 400 before any token is generated:

    Extra inputs are not permitted, field: 'serviceTier', value: 'priority'
    

    Notes

    • The picker's "Priority" variants inject serviceTier: "priority" (camelCase) as a variant setting, which @ai-sdk/openai-compatible forwards verbatim into the JSON body. Fireworks' strict Pydantic schema (extra="forbid") only accepts the snake_case service_tier key, so the request fails validation.
    • Only the dedicated OpenAI/Fireworks SDK paths translate serviceTier → service_tier; raw pass-through on openai-compatible providers hits the same problem as the reasoningEffort cases above.
    • Confirms the camelCase variant-settings bug also affects the serviceTier setting and predates the v2 rewrite.
  3. opencodejr commented on Oct 28, 2026

    @opencodejr

    Thanks for the detailed report. I tried to reproduce this on 0.0.0-next-17276, the build you reported, using the stock catalog. I pointed fireworks-ai, huggingface and togetherai at a local server that records the request body and rejects reasoningEffort the way Fireworks does. Then I ran e.g. opencode2 run -m 'fireworks-ai/accounts/fireworks/models/kimi-k3#max' ping.

    In every case the variant was sent as snake_case "reasoning_effort": "max" (or "high"). No reasoningEffort key appeared, and the requests succeeded. That held for Fireworks kimi-k3 and for moonshotai/Kimi-K3 on Hugging Face and Together AI. So the stock catalog path on its own doesn't seem to produce the camelCase key.

    These would help narrow it down:

    • Does it still happen with all plugins disabled? oc-codex-multi-auth, @tarquinen/opencode-dcp and @plannotator/opencode can change provider options or request bodies.
    • Does it happen when you pick the variant directly (-m provider/model#max), or only through a subagent with variant: max? If only the subagent, please share that agent's definition.
    • Does it still happen on the current release (npm i -g @opencode/cli@latest, currently 2.2.0)?
    • Please share the relevant part of the log from a failing request.

    Related: #53975 (open PR changing which settings are passed to OpenAI-compatible endpoints) and #48183 (variant settings shape for OpenAI-compatible providers, fixed in 2.0.0).

  4. opencodejr commented on Oct 31, 2026

    @opencodejr

    I'm closing this for now because we haven't heard back. On 0.0.0-next-17276, the stock catalog variants for Fireworks kimi-k3, Hugging Face and Together AI Kimi-K3 were all sent as snake_case reasoning_effort, and the requests succeeded. So we couldn't reproduce the camelCase reasoningEffort key without your plugins or the subagent setup.

    If it still happens, especially on the current release (npm i -g @opencode/cli@latest) or with plugins disabled, please comment here with the details asked for above (plugins on or off, direct #variant or subagent, and logs from a failing request). We'll reopen it.

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions