Skip to content

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

Open

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.
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