unslothai/unsloth · error · HTTPException

Cannot replace and clear an API key in the same request

Error message

Cannot replace and clear an API key in the same request

What it means

A 400 from PUT /api/providers/{provider_id}: the request set both clear_api_key=true and a non-empty encrypted_api_key. These are mutually exclusive operations — replacing a key and clearing it cannot happen in one atomic request — so the backend rejects the combination before touching storage.

Source

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

    existing_info = get_provider_info(existing["provider_type"]) or {}
    max_output_tokens_requested = "max_output_tokens" in payload.model_fields_set
    _validate_max_output_tokens_contract(
        existing["provider_type"],
        max_output_tokens_requested,
        payload.max_output_tokens,
    )
    _validate_provider_auth_contract(
        existing_info,
        encrypted_api_key = payload.encrypted_api_key,
        base_url = payload.base_url,
        models = payload.models,
        updating = True,
        clear_api_key = payload.clear_api_key,
    )

    if payload.clear_api_key and payload.encrypted_api_key:
        raise HTTPException(
            status_code = 400,
            detail = "Cannot replace and clear an API key in the same request",
        )

    metadata_fields = {
        "display_name",
        "base_url",
        "is_enabled",
        "models",
        "available_models",
        "max_output_tokens",
    }
    metadata_requested = bool(payload.model_fields_set & metadata_fields)

    # Only a *changed* base URL is validated. The dialog re-sends the stored value
    # on every edit, so validating an unchanged legacy row would lock the user out
    # of editing its models or API key. Outbound use is still checked.
    base_url = payload.base_url

View on GitHub (pinned to 203007d190)

Solutions

  1. Send either encrypted_api_key (replace) or clear_api_key: true (remove), never both.
  2. Reset the 'clear key' checkbox whenever the user types a new key in the form.
  3. In API clients, make these two distinct code paths or buttons.

Example fix

// before
await putProvider(id, { encrypted_api_key: newKey, clear_api_key: clearChecked });
// after
const body = { display_name };
if (newKey) body.encrypted_api_key = newKey;
else if (clearChecked) body.clear_api_key = true;
Defensive patterns

Strategy: validation

Validate before calling

if (body.clear_api_key && body.encrypted_api_key) {
  throw new Error("Send either encrypted_api_key or clear_api_key, not both");
}

Prevention

When it happens

Trigger: An edit form that submits the key field from a 'replace key' input while a separate 'remove key' checkbox is also ticked; client code that always includes clear_api_key and happens to include a key payload.

Common situations: Dialogs offering both actions simultaneously; state bugs where a previously-ticked clear checkbox is never reset; bulk-sync scripts sending superset payloads.

Related errors


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