mudler/LocalAI · error · ValueError

{raw!r} is not a boolean

Error message

{raw!r} is not a boolean

What it means

Raised by _coerce_option in the vLLM backend's shared utils when a CLI-supplied string must be coerced to a boolean field but its lowercased value is in neither the truthy nor falsy sets. It guards engine_args validation: any bool-typed ServerArgs field given an unrecognized literal reaches this branch.

Source

Thrown at backend/python/common/vllm_utils.py:108


def _type_hint(annotation, current):
    """Best-effort target type name for a dataclass field."""
    hint = _hint_from_annotation(annotation)
    if hint is None:
        hint = _hint_from_value(current)
    return hint


def _coerce_option(raw, hint):
    """Coerce a CLI-supplied string to the field's type. Raises ValueError."""
    if hint == "bool":
        low = raw.lower()
        if low in _TRUTHY:
            return True
        if low in _FALSY:
            return False
        raise ValueError(f"{raw!r} is not a boolean")
    if hint == "int":
        return int(raw)
    if hint == "float":
        return float(raw)
    if hint == "dict":
        return json.loads(raw)
    if hint == "str":
        return raw

    # Untyped (or union-typed) field: infer from the literal itself.
    low = raw.lower()
    if low in _TRUTHY:
        return True
    if low in _FALSY:
        return False
    for cast in (int, float):
        try:
            return cast(raw)

View on GitHub (pinned to 44413a9d06)

Solutions

  1. Use canonical boolean literals: true/false (case-insensitive) or whatever _TRUTHY/_FALSY in vllm_utils define — check those sets for the exact accepted spellings.
  2. Strip whitespace and remove surrounding quotes in the config value.
  3. If the value comes from a user-supplied config, normalize it upstream (e.g. 'yes'→'true') before passing engine args.
  4. Check whether the intended field is actually bool-typed in the installed vLLM ServerArgs; a version change may have altered the type hint and hence the coercion path.

Example fix

# before
options = {"enforce_eager": "yes"}

# after
options = {"enforce_eager": "true"}
Defensive patterns

Strategy: validation

Validate before calling

_BOOL_LITERALS = {"true", "false", "1", "0", "yes", "no"}  # align with _TRUTHY/_FALSY
def is_coercible_bool(raw: str) -> bool:
    return raw.strip().lower() in _BOOL_LITERALS

Type guard

def is_valid_engine_option(raw: str, hint: str) -> bool:
    if hint == "bool":
        return raw.strip().lower() in _TRUTHY | _FALSY
    try:
        {"int": int, "float": float, "dict": lambda s: json.loads(s)}.get(hint, lambda s: s)(raw)
        return True
    except (ValueError, json.JSONDecodeError):
        return False

Try / catch

try:
    value = _coerce_option(raw_value, "bool")
except ValueError:
    value = raw_value.strip().lower() in ("true", "1")
    logger.warning("non-canonical boolean %r coerced to %s", raw_value, value)

Prevention

When it happens

Trigger: Passing a string like 'yes', 'on', 'enabled', '1.0', or 'true ' (with whitespace/typo) via backend options/CLI flags for a field whose type hint resolves to bool, where _TRUTHY/_FALSY only cover the canonical literals (true/false, 1/0, etc. depending on the sets defined in the module).

Common situations: Users writing 'yes'/'no' or 'on'/'off' in YAML/JSON backend config, shell-quoting mistakes that append whitespace, or copy-pasting flags from vLLM docs that use different boolean spellings than LocalAI's accepted set.

Related errors


AI-assisted analysis of mudler/LocalAI@44413a9d06 (2026-08-15). Data as JSON: /api/errors/333d218bad5ee1d3. Report an issue: GitHub.