{"record":{"id":"63cdf86a2f932ff3","repo":"unslothai/unsloth","slug":"auto-unload-idle-seconds-must-be-a-non-negative-in","errorCode":null,"errorMessage":"Auto-unload idle seconds must be a non-negative integer.","messagePattern":"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":296,"sourceCode":"\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 \"\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)","sourceCodeStart":278,"sourceCodeEnd":314,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/utils/openai_auto_switch_settings.py#L278-L314","documentation":"Raised by set_openai_auto_switch in openai_auto_switch_settings.py:296 when idle_seconds is provided but _coerce_int returns None. _coerce_int does max(0, int(value)); it fails (returns None) for None-like values, non-numeric strings, floats with decimals like \"1.5\", and containers. Negative ints are clamped to 0, not rejected here.","triggerScenarios":"set_openai_auto_switch(enabled=True, idle_seconds=\"90s\"), idle_seconds=1.5 (float with fraction via string), idle_seconds=\"1.5\", or idle_seconds=[90]. Also idle_seconds=\"\" or a dict.","commonSituations":"UI sends the raw text-field value (\"120s\", \"1.5\", \"\") instead of a parsed integer; configs carry floats; unit tests pass Decimal or float types.","solutions":["Parse the input to an int before calling (e.g. int(str(value).strip()) with try/except)","Send plain integers or integer strings like \"120\" from the client","Reject fractional idle values in the form/UI layer","Remember 0 means 'off' and negatives are clamped to 0, so only malformed types reach this error"],"exampleFix":"# before\nset_openai_auto_switch(enabled=True, idle_seconds=\"90s\")\n\n# after\nseconds = int(\"90\")\nset_openai_auto_switch(enabled=True, idle_seconds=seconds)","handlingStrategy":"validation","validationCode":"def parse_idle_seconds(v) -> int | None:\n    try:\n        return max(0, int(str(v).strip()))\n    except (TypeError, ValueError):\n        return None\n\nparsed = parse_idle_seconds(idle_seconds)\nif idle_seconds is not None and parsed is None:\n    raise HTTPException(400, \"idle_seconds must be a non-negative integer\")","typeGuard":"def is_coercible_int(v: object) -> bool:\n    try:\n        int(v)\n        return True\n    except (TypeError, ValueError):\n        return False","tryCatchPattern":"try:\n    set_openai_auto_switch(enabled=True, idle_seconds=idle_seconds)\nexcept ValueError as exc:\n    return {\"ok\": False, \"error\": str(exc)}, 400","preventionTips":["Strip units ('s', ' sec') in the UI before submitting","Use integer-only inputs for idle fields","Round floats deliberately; reject fractional idles"],"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"}