Bug: coerce_to_type treats string "false" as True for BOOLEAN schema
Bug: coerce_to_type treats string "false" as True for BOOLEAN schema
Problem
coerce_to_type (guardrails/utils/parsing_utils.py) uses coerce(payload, bool) for BOOLEAN schema types, which calls Python bool() on the payload. For strings like "false", "0", "no", bool() returns True (any non-empty string is truthy in Python).
This means when an LLM returns the string "false" and the schema expects a boolean, it gets incorrectly coerced to True — a critical correctness bug in a validation framework.
Root Cause
# guardrails/utils/parsing_utils.py, coerce_to_type()
elif schema_type == SimpleTypes.BOOLEAN:
if not isinstance(payload, bool):
return coerce(payload, bool) # bool("false") → True (bug!)
return payloadcoerce("false", bool) → bool("false") → True (non-empty string is truthy).
Note: guardrails/utils/casting_utils.py already has a to_bool() function that correctly handles "true"/"false", but coerce_to_type doesn't use it.
Reproduce
from guardrails.utils.parsing_utils import coerce_to_type
from guardrails.types.simple import SimpleTypes
assert coerce_to_type("false", SimpleTypes.BOOLEAN) is True # Bug! Should be False
assert coerce_to_type("0", SimpleTypes.BOOLEAN) is True # Bug! Should be FalseProposed Fix
Add explicit string-to-bool parsing in the BOOLEAN branch before falling back to coerce():
elif schema_type == SimpleTypes.BOOLEAN:
if not isinstance(payload, bool):
if isinstance(payload, str):
lower = payload.strip().lower()
if lower in ("false", "0", "no", "off"):
return False
if lower in ("true", "1", "yes", "on"):
return True
return coerce(payload, bool)
return payloadPR
#1557 — 13 parametrized test cases passed.
Source: guardrails-ai/guardrails