unslothai/unsloth · warning · HTTPException

is_enabled must be true or false

Error message

is_enabled must be true or false

What it means

400 from _changes_from_payload when the update payload explicitly includes is_enabled but its value is null. Because is_enabled is a tri-state in the update model (absent = don't change, true/false = set), null is neither and is rejected — the column is NOT NULL semantically.

Source

Thrown at studio/backend/routes/mcp_servers.py:192


def _changes_from_payload(payload: McpServerUpdate) -> dict:
    sent = payload.model_fields_set
    changes: dict = {}

    if "display_name" in sent:
        name = (payload.display_name or "").strip()
        if not name:
            raise HTTPException(status_code = 400, detail = "display_name must not be empty")
        changes["display_name"] = name
    if "url" in sent:
        changes["url"] = _validate_url(payload.url or "")
    if "headers" in sent:
        headers = _normalize_headers(payload.headers)
        changes["headers_json"] = json.dumps(headers) if headers else None
    if "is_enabled" in sent:
        if payload.is_enabled is None:
            raise HTTPException(status_code = 400, detail = "is_enabled must be true or false")
        changes["is_enabled"] = payload.is_enabled
    if "use_oauth" in sent:
        if payload.use_oauth is None:
            raise HTTPException(status_code = 400, detail = "use_oauth must be true or false")
        changes["use_oauth"] = payload.use_oauth
    # stdio is OAuth-less: drop a stale OAuth flag when switching to a command.
    if "url" in changes and is_stdio(changes["url"]):
        changes["use_oauth"] = False
    return changes


@router.put("/{server_id}", response_model = McpServerResponse)
async def update_mcp_server(
    server_id: str,
    payload: McpServerUpdate,
    current_subject: str = Depends(get_current_subject),
    via_api_key: ViaApiKey = False,
):

View on GitHub (pinned to 203007d190)

Solutions

  1. Send true or false, e.g. {"is_enabled": false} to disable the server.
  2. Omit the key when the toggle state shouldn't change.
  3. Normalize client state to booleans before sending (Boolean(value) or !!value).

Example fix

// before
await api.put(`/api/mcp-servers/${id}`, {is_enabled: toggled ? true : null});

// after
await api.put(`/api/mcp-servers/${id}`, {is_enabled: !!toggled});
Defensive patterns

Strategy: type-guard

Validate before calling

if ('is_enabled' in payload) {
  if (typeof payload.is_enabled !== 'boolean') throw new Error('is_enabled must be true or false');
}

Type guard

const isBoolOrNull = (v) => v === null || typeof v === 'boolean';
function validEnabledUpdate(p) { return !('is_enabled' in p) || typeof p.is_enabled === 'boolean'; }

Prevention

When it happens

Trigger: PUT /{server_id} with {"is_enabled": null} in the body (key present, value null).

Common situations: JS clients whose state uses null for unchecked/unknown toggles; spreading a partially-filled form object into the PUT body.

Related errors


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