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
- Remove max_output_tokens or send null for built-in provider types.
- If you genuinely need an override, change the provider row to provider_type 'custom'.
- 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
- Only show a max-tokens input for provider_type 'custom'.
- Serialise blank inputs as null, never as a number or empty string.
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
- model load did not reach ready
- unknown family '{name}'
- Refused notebook fetch from {host!r}: not in allowlist {sort
- Cell uses shell metacharacters / interpolation but --no-allo
- load error: {backend.load_progress()}
AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15).
Data as JSON: /api/errors/90a2da881e9b602b.
Report an issue: GitHub.