{"record":{"id":"8ac570268d5e308a","repo":"unslothai/unsloth","slug":"auto-unload-idle-seconds-must-be-0-off-or-at-lea","errorCode":null,"errorMessage":"Auto-unload idle seconds must be 0 (off) or at least {MIN_AUTO_UNLOAD_IDLE_SECONDS}.","messagePattern":"Auto-unload idle seconds must be 0 \\(off\\) or at least (.+?)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"studio/backend/utils/openai_auto_switch_settings.py","lineNumber":298,"sourceCode":"def 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 \"\n                f\"{MIN_AUTO_UNLOAD_IDLE_SECONDS}.\"\n            )\n    parsed_keep_kv = None\n    if keep_kv is not None:\n        parsed_keep_kv = _coerce_bool(keep_kv)\n        if parsed_keep_kv is None:\n            raise ValueError(\"Keep KV on idle unload must be true or false.\")","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/utils/openai_auto_switch_settings.py#L280-L316","documentation":"Raised by set_openai_auto_switch in openai_auto_switch_settings.py:297-301. idle_seconds must be either 0 (auto-unload disabled) or at least MIN_AUTO_UNLOAD_IDLE_SECONDS, which is 60 in this codebase. Any value strictly between 1 and 59 is rejected to prevent thrashing models in and out of memory.","triggerScenarios":"set_openai_auto_switch(enabled=True, idle_seconds=30) — any of 1..59 raises. idle_seconds=0 and idle_seconds>=60 are accepted; negatives were clamped to 0 by _coerce_int.","commonSituations":"Users trying aggressive unload timeouts like 10-30 seconds; UI sliders that allow sub-minute values; migrations from configs where the minimum used to be lower.","solutions":["Use 0 to disable auto-unload, or any value >= 60 (e.g. 120)","Clamp in the UI: slider minimum 60 with a separate 'off' option","Update stale documentation or config files that suggest 30-second idles","Programmatically normalize: value = 0 if value < 60 else value"],"exampleFix":"# before\nset_openai_auto_switch(enabled=True, idle_seconds=30)\n\n# after\nset_openai_auto_switch(enabled=True, idle_seconds=0)  # off\n# or\nset_openai_auto_switch(enabled=True, idle_seconds=120)","handlingStrategy":"validation","validationCode":"MIN_IDLE = 60\n\ndef valid_idle(v: int) -> bool:\n    return v == 0 or v >= MIN_IDLE","typeGuard":"def is_valid_idle_seconds(v: object) -> bool:\n    if not isinstance(v, int) or isinstance(v, bool):\n        return False\n    return v == 0 or v >= 60","tryCatchPattern":"try:\n    set_openai_auto_switch(enabled=True, idle_seconds=idle)\nexcept ValueError as exc:\n    if \"at least\" in str(exc):\n        idle = 0 if idle < 60 else idle  # prompt user instead in real UI\n    raise","preventionTips":["Offer only 'off (0)' or values >= 60 in the UI","Document the 60-second floor next to the setting","Clamp old configs on migration: below 60 becomes 0 or 60"],"tags":["settings","validation","range-check"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}