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
- Use canonical boolean literals: true/false (case-insensitive) or whatever _TRUTHY/_FALSY in vllm_utils define — check those sets for the exact accepted spellings.
- Strip whitespace and remove surrounding quotes in the config value.
- If the value comes from a user-supplied config, normalize it upstream (e.g. 'yes'→'true') before passing engine args.
- 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
- Normalize boolean config values to true/false at the config layer.
- Strip whitespace and quotes when ingesting user-supplied engine args.
- Validate the whole engine-args dict once at startup, not per request.
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
- unknown engine: {name!r}
- resolution must be 480p or 720p
- base_model must point to a LongCat-Video checkpoint
- request needs {segments} avatar segments, but max_segments i
- {name} must be true or false
AI-assisted analysis of mudler/LocalAI@44413a9d06 (2026-08-15).
Data as JSON: /api/errors/333d218bad5ee1d3.
Report an issue: GitHub.