unslothai/unsloth · warning · HTTPException

use_oauth must be true or false

Error message

use_oauth must be true or false

What it means

400 from _changes_from_payload when the update payload includes use_oauth but sets it to null. The OAuth flag must be a definite boolean on update (absent = unchanged; true/false = set), and null would leave the probe path ambiguous, so it's rejected before any change is applied.

Source

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

    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,
):
    old = mcp_servers_db.get_server(server_id)
    if not old:
        raise HTTPException(status_code = 404, detail = "MCP server not found")
    changes = _changes_from_payload(payload)

View on GitHub (pinned to 203007d190)

Solutions

  1. Send {"use_oauth": true} or {"use_oauth": false}, or omit the key to leave it unchanged.
  2. Rely on the server's automatic use_oauth=false when repointing a row at a stdio command instead of clearing it manually.
  3. Exclude null-valued keys when serializing update payloads.

Example fix

# before
client.put(f'/api/mcp-servers/{sid}', json={'use_oauth': None})
# -> 400

# after
client.put(f'/api/mcp-servers/{sid}', json={'use_oauth': False})
# or omit the key entirely
Defensive patterns

Strategy: type-guard

Validate before calling

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

Type guard

function validOAuthUpdate(p) { return !('use_oauth' in p) || typeof p.use_oauth === 'boolean'; }

Prevention

When it happens

Trigger: PUT /{server_id} with {"use_oauth": null} in the body. Note the backend itself forces use_oauth=false when the url switches to a stdio command, so clients never need to send null to clear it.

Common situations: Reset-style forms that send null to 'clear' the OAuth toggle; API wrappers that include every field with null defaults.

Related errors


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