Hmbown/CodeWhale · error

maxOutputTokens is unsupported by the selected provider…

Error message

maxOutputTokens is unsupported by the selected provider transport

What it means

When max_output_tokens is set, the runtime checks the resolved route's provider/protocol via route_supports_output_token_limit; if that transport cannot carry an output-token cap (provider + protocol combination), the turn is rejected rather than silently dropping the budget.

Solutions

  1. Choose a model/provider whose transport supports output token limits.
  2. Drop max_output_tokens from the request for this transport.
  3. Extend route_supports_output_token_limit if the transport actually supports budgets but is unlisted.

Example fix

// before
req.model = "custom-protocol-model".into();
req.max_output_tokens = Some(2048);
// after
req.model = "openai-compatible-model".into();
req.max_output_tokens = Some(2048);
Defensive patterns

Strategy: validation

Validate before calling

if req.max_output_tokens.is_some() && !route_supports_output_token_limit(route.identity.provider, route.candidate.protocol()) {
    req.max_output_tokens = None; // drop the budget for this transport
}

Type guard

fn transport_supports_token_limit(route: &Route) -> bool { route_supports_output_token_limit(route.identity.provider, route.candidate.protocol()) }

Prevention

When it happens

Trigger: Setting req.max_output_tokens with an exact model whose resolved route's provider/protocol pair is not in route_supports_output_token_limit (e.g. a protocol without token-budget parameters).

Common situations: Pointing a thread at a provider transport (custom/OAuth protocol variant) that has no max_tokens field; switching a thread from OpenAI-compatible to a protocol lacking budget support while keeping token limits configured.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/028739f66496a1b0. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/runtime_threads.rs:9920

                request_fingerprint,
                reserved_turn_id,
            )?
        } else {
            None
        };
        if let Some(operation) = operation.as_ref()
            && let Some(original_turn) = self.replay_turn_for_operation(operation)?
        {
            return Ok((original_turn, true));
        }
        if !image_blocks.is_empty() || req.max_output_tokens.is_some() {
            let identity = self.provider_identity_for_thread(&cfg_snapshot, &thread)?;
            let route = resolve_runtime_thread_route_for_identity(&cfg_snapshot, &identity, Some(&requested_model))?;
            if !image_blocks.is_empty() && route.candidate.capabilities().image_input != codewhale_config::route::CapabilityState::Supported {
                bail!("image inputs require a model with explicitly supported image input");
            }
            if req.max_output_tokens.is_some() && !crate::route_budget::route_supports_output_token_limit(route.identity.provider, route.candidate.protocol()) {
                bail!("maxOutputTokens is unsupported by the selected provider transport");
            }
        }
        let engine = self.ensure_engine_loaded(&thread).await?;

        let client_preflight_required = {
            let active = self.active.lock().await;
            if let Some(active_thread) = active.engines.get(thread_id)
                && active_thread.active_turn.is_some()
            {
                bail!("Thread already has an active turn");
            }
            active
                .engines
                .get(thread_id)
                .is_none_or(|state| state.client_preflight_required)
        };

        // Resolve the concrete provider/model before persisting a turn. Auto

View on GitHub (pinned to 73e0f67d83)