{"record":{"id":"f4d2721c8a856922","repo":"unslothai/unsloth","slug":"media-auto-unload-idle-seconds-must-be-a-non-negat","errorCode":null,"errorMessage":"Media auto-unload idle seconds must be a non-negative integer.","messagePattern":"Media auto-unload idle seconds must be a non-negative integer\\.","errorType":"validation","errorClass":"ValueError","httpStatus":400,"severity":"error","filePath":"studio/backend/utils/openai_auto_switch_settings.py","lineNumber":306,"sourceCode":"    \"\"\"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.\")\n    parsed_auto_download = None\n    if auto_download is not None:\n        parsed_auto_download = _coerce_bool(auto_download)\n        if parsed_auto_download is None:\n            raise ValueError(\"Auto-download missing models must be true or false.\")\n    parsed_api_only = None\n    if api_only is not None:\n        parsed_api_only = _coerce_bool(api_only)","sourceCodeStart":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/utils/openai_auto_switch_settings.py#L288-L324","documentation":"Raised by set_openai_auto_switch in openai_auto_switch_settings.py:305-306 when media_idle_seconds is provided but _coerce_int cannot parse it — same coercion rules as the main idle: int() must succeed; decimals-as-strings (\"1.5\"), non-numeric strings, lists, dicts, and empty strings all fail. Negative ints are clamped to 0.","triggerScenarios":"set_openai_auto_switch(enabled=True, media_idle_seconds=\"45s\"), media_idle_seconds=2.5, media_idle_seconds=\"\", or media_idle_seconds=None-as-string. Note Python None is fine (leaves the stored value untouched).","commonSituations":"Media/GPU idle settings entered as free text in the UI; JSON configs with floats; copy-pasting '90 sec' from documentation.","solutions":["Parse to int before calling; strip units in the UI layer","Send plain integers or integer strings","Reject fractional values client-side","Leave the argument as Python None (or omit it) to keep the stored value"],"exampleFix":"# before\nset_openai_auto_switch(enabled=True, media_idle_seconds=\"1.5\")\n\n# after\nset_openai_auto_switch(enabled=True, media_idle_seconds=90)","handlingStrategy":"validation","validationCode":"def parse_media_idle(v) -> int | None:\n    if v is None:\n        return None\n    try:\n        return max(0, int(str(v).strip()))\n    except (TypeError, ValueError):\n        return None","typeGuard":"def is_coercible_nonneg_int(v: object) -> bool:\n    try:\n        return int(v) >= 0\n    except (TypeError, ValueError):\n        return False","tryCatchPattern":"try:\n    set_openai_auto_switch(enabled=True, media_idle_seconds=media_idle)\nexcept ValueError as exc:\n    raise HTTPException(400, str(exc)) from exc","preventionTips":["Use a numeric input with integer step for media idle","Pass Python None to leave the stored value untouched","Never forward raw text-field strings"],"tags":["settings","validation","integer-coercion"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}