unslothai/unsloth · error · ValueError

Keep model in GPU memory must be true or false.

Error message

Keep model in GPU memory must be true or false.

What it means

set_model_memory_settings() coerces the keep_resident argument with _coerce_bool(); if the value is non-None but not recognizable as a boolean (not bool, not 0/1, not 'true'/'false'-style strings), _coerce_bool returns None and this ValueError fires. The message names the UI toggle ('Keep model in GPU memory') the API field maps to.

Source

Thrown at studio/backend/utils/model_memory_settings.py:146

    pair = (get_keep_resident(), get_no_ram_reserve())
    for _attempt in range(_MAX_REREADS):
        before = _pair_generations()
        pair = (get_keep_resident(), get_no_ram_reserve())
        if _pair_generations() == before:
            return pair
    return pair


def set_model_memory_settings(
    keep_resident: Any = None, no_ram_reserve: Any = None
) -> tuple[bool, bool]:
    """One-transaction write; ``None`` leaves a stored value untouched."""
    updates: dict[str, bool] = {}

    if keep_resident is not None:
        parsed = _coerce_bool(keep_resident)
        if parsed is None:
            raise ValueError("Keep model in GPU memory must be true or false.")
        updates[KEEP_RESIDENT_SETTING_KEY] = parsed

    if no_ram_reserve is not None:
        parsed = _coerce_bool(no_ram_reserve)
        if parsed is None:
            raise ValueError("Do not reserve system RAM must be true or false.")
        updates[NO_RAM_RESERVE_SETTING_KEY] = parsed

    if updates:
        from storage.studio_db import upsert_app_settings
        upsert_app_settings(updates)
        _invalidate(*updates)

    return get_keep_resident(), get_no_ram_reserve()


def memlock_limit_bytes() -> Optional[int]:
    """Soft RLIMIT_MEMLOCK, or None when unlimited or unavailable.

View on GitHub (pinned to 203007d190)

Solutions

  1. Send an actual JSON boolean: set_model_memory_settings(keep_resident=True)
  2. If the value is a string, normalize to 0/1 or 'true'/'false' before calling (check _coerce_bool's accepted forms)
  3. Omit the field (or pass None) when you do not intend to change it

Example fix

# before
set_model_memory_settings(keep_resident='yes')
# ValueError: Keep model in GPU memory must be true or false.

# after
set_model_memory_settings(keep_resident=True)
Defensive patterns

Strategy: type-guard

Validate before calling

def is_bool_like(v) -> bool:
    return v is None or isinstance(v, bool) or v in (0, 1) or str(v).strip().lower() in ('true', 'false')

if not is_bool_like(payload.get('keep_resident')):
    return 400 'keep_resident must be a boolean'

Type guard

def coerce_bool_or_none(v):
    if v is None or isinstance(v, bool):
        return v
    if isinstance(v, int) and v in (0, 1):
        return bool(v)
    if isinstance(v, str) and v.strip().lower() in ('true', 'false'):
        return v.strip().lower() == 'true'
    return None  # caller rejects

Try / catch

try:
    set_model_memory_settings(keep_resident=v)
except ValueError as e:
    return 422 {'detail': str(e)}

Prevention

When it happens

Trigger: set_model_memory_settings(keep_resident='yes'), keep_resident=2, keep_resident='on', or keep_resident=[] — anything truthy-looking but outside _coerce_bool's accepted forms. Passing None is the sanctioned 'leave unchanged' path and never raises.

Common situations: A frontend sending checkbox tri-state values ('yes'/'no'), sending integers other than 0/1, or a client serializing booleans as strings without normalization; API consumers guessing the payload shape.

Related errors


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