{"record":{"id":"f4557d50edcc3793","repo":"unslothai/unsloth","slug":"openai-auto-switch-must-be-true-or-false","errorCode":null,"errorMessage":"OpenAI auto-switch must be true or false.","messagePattern":"OpenAI auto-switch must be true or false\\.","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"studio/backend/utils/openai_auto_switch_settings.py","lineNumber":291,"sourceCode":"\ndef get_auto_unload_api_only() -> bool:\n    \"\"\"Whether the idle unload spares models a user loaded from the UI.\"\"\"\n    parsed = _coerce_bool(_cached_setting(AUTO_UNLOAD_API_ONLY_SETTING_KEY, None))\n    return parsed if parsed is not None else DEFAULT_AUTO_UNLOAD_API_ONLY\n\n\ndef set_openai_auto_switch(\n    enabled: Any,\n    idle_seconds: Any,\n    keep_kv: Any = None,\n    auto_download: Any = None,\n    api_only: Any = None,\n    media_idle_seconds: Any = None,\n) -> tuple[bool, int, bool, bool, bool, int]:\n    \"\"\"One-transaction write; ``None`` leaves a stored value untouched.\"\"\"\n    parsed_enabled = _coerce_bool(enabled)\n    if parsed_enabled is None:\n        raise ValueError(\"OpenAI auto-switch must be true or false.\")\n    parsed_idle = None\n    if idle_seconds is not None:\n        parsed_idle = _coerce_int(idle_seconds)\n        if parsed_idle is None:\n            raise ValueError(\"Auto-unload idle seconds must be a non-negative integer.\")\n        if 0 < parsed_idle < MIN_AUTO_UNLOAD_IDLE_SECONDS:\n            raise ValueError(\n                f\"Auto-unload idle seconds must be 0 (off) or at least \"\n                f\"{MIN_AUTO_UNLOAD_IDLE_SECONDS}.\"\n            )\n    parsed_media_idle = None\n    if media_idle_seconds is not None:\n        parsed_media_idle = _coerce_int(media_idle_seconds)\n        if parsed_media_idle is None:\n            raise ValueError(\"Media auto-unload idle seconds must be a non-negative integer.\")\n        if 0 < parsed_media_idle < MIN_AUTO_UNLOAD_IDLE_SECONDS:\n            raise ValueError(\n                f\"Media auto-unload idle seconds must be 0 (off) or at least \"","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/utils/openai_auto_switch_settings.py#L273-L309","documentation":"Raised by set_openai_auto_switch in openai_auto_switch_settings.py:291 when the enabled argument cannot be coerced to bool. _coerce_bool accepts real bools plus the strings \"1/true/yes/on\" and \"0/false/no/off\" (case-insensitive, trimmed). Notably it does NOT accept integers: passing 1 or 0 raises this error because isinstance(1, bool) is False.","triggerScenarios":"Calling set_openai_auto_switch(enabled=1), set_openai_auto_switch(enabled=\"enable\"), or passing None. Also any int/float value, or unrecognized strings like \"y\"/\"enabled\".","commonSituations":"Frontend or API client sends JSON true/false that gets coerced to 1/0 by a middleware; scripts pass Python ints; query-string parsing yields unhandled tokens like \"enabled\".","solutions":["Pass an actual bool: enabled=True / enabled=False","If the value comes from user input, normalize with the same tokens: strip+lowercase and accept 1/true/yes/on vs 0/false/no/off","Change the client to send JSON booleans, not 0/1","Validate with _coerce_bool before calling and map failures to a user-facing form error"],"exampleFix":"# before\nset_openai_auto_switch(enabled=1, idle_seconds=120)  # int -> ValueError\n\n# after\nset_openai_auto_switch(enabled=True, idle_seconds=120)","handlingStrategy":"validation","validationCode":"def coerce_setting_bool(v) -> bool | None:\n    if isinstance(v, bool):\n        return v\n    if isinstance(v, str):\n        n = v.strip().lower()\n        if n in {\"1\", \"true\", \"yes\", \"on\"}: return True\n        if n in {\"0\", \"false\", \"no\", \"off\", \"\"}: return False\n    return None\n\nif coerce_setting_bool(enabled) is None:\n    raise HTTPException(400, \"enabled must be a boolean\")","typeGuard":"def is_settable_bool(v: object) -> bool:\n    if isinstance(v, bool):\n        return True\n    return isinstance(v, str) and v.strip().lower() in {\"1\",\"true\",\"yes\",\"on\",\"0\",\"false\",\"no\",\"off\",\"\"}","tryCatchPattern":"try:\n    set_openai_auto_switch(enabled=raw_enabled)\nexcept ValueError as exc:\n    raise HTTPException(400, str(exc)) from exc","preventionTips":["Pass real Python bools, never 0/1 ints","Apply the same token whitelist in your form parser","Reject the request at the schema layer when enabled is not boolean"],"tags":["settings","validation","boolean-coercion"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}