unslothai/unsloth · error · HTTPException

Max Tokens limit can only be overridden for generic Custom p

Error message

Max Tokens limit can only be overridden for generic Custom providers.

What it means

A 400 from _validate_max_output_tokens_contract: the request explicitly set max_output_tokens to a non-null value on a provider whose provider_type is not 'custom'. Documented caps exist for built-in provider types, so an override is only meaningful for generic Custom providers; an explicit null is always allowed and clearing is a no-op.

Source

Thrown at studio/backend/routes/providers.py:128

        raise HTTPException(status_code = 400, detail = "ChatGPT subscription routing is fixed.")
    if models is not None and (not models or not set(models).issubset(set(info["default_models"]))):
        raise HTTPException(status_code = 400, detail = "Choose only curated Codex models.")


def _validate_max_output_tokens_contract(
    provider_type: str,
    field_was_set: bool,
    value: Optional[int] = None,
) -> None:
    """Reject a non-null override on a provider type with its own documented caps.

    An explicit null is allowed through everywhere: the dialog shows the field for rows
    it displays as Custom but the backend stores as `openai`, and a blank field
    serialises as null, so rejecting it failed every unrelated edit of those rows.
    Clearing an override that cannot exist is a no-op.
    """
    if field_was_set and value is not None and provider_type != "custom":
        raise HTTPException(
            status_code = 400,
            detail = "Max Tokens limit can only be overridden for generic Custom providers.",
        )


# ── Public key for API key encryption ─────────────────────────────


@router.get("/public-key")
async def get_public_key(current_subject: str = Depends(get_current_subject)):
    """Return the RSA public key PEM for client-side API key encryption.

    ``fingerprint`` is a short SHA256 of the PEM; a mismatch with what the
    frontend captured at encrypt time signals the keypair rotated mid-flight.
    """
    return {
        "public_key": get_public_key_pem(),
        "fingerprint": get_public_key_fingerprint(),

View on GitHub (pinned to 203007d190)

Solutions

  1. Remove max_output_tokens or send null for built-in provider types.
  2. If you genuinely need an override, change the provider row to provider_type 'custom'.
  3. Fix the client to distinguish 'field blank' (send null) from 'field set' (send only for custom).

Example fix

// before
await putProvider(id, { max_output_tokens: Number(input.value) });
// after
const raw = input.value.trim();
const body = {};
if (raw !== "" && providerType === "custom") {
  body.max_output_tokens = Number(raw);
} else {
  body.max_output_tokens = null; // explicit clear is allowed
}
Defensive patterns

Strategy: validation

Validate before calling

function normalizeMaxTokens(providerType, raw) {
  if (raw === "" || raw == null) return null; // explicit clear, always allowed
  if (providerType !== "custom") return null;  // ignore for built-in types
  return Number(raw);
}

Prevention

When it happens

Trigger: POST/PUT with max_output_tokens: 4096 on a provider_type like 'openai' or 'anthropic'; a dialog that serialises a blank field as a number instead of null; migration scripts copying max_output_tokens onto built-in types.

Common situations: Reused edit forms that always include max_output_tokens; blank-vs-null serialisation bugs in the client; users trying to raise caps on curated provider types.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/90a2da881e9b602b. Report an issue: GitHub.