crewAIInc/crewAI · error · ValueError

invalid value to cast to bool: {val!r}

Error message

invalid value to cast to bool: {val!r}

What it means

Raised by the boolean coercion helper in file_writer_tool when a string value is not one of the recognized boolean spellings ('y','yes','t','true','on','1' / 'n','no','f','false','off','0'). The tool accepts booleans as strings (because LLM tool args arrive as text) and this guard rejects ambiguous input rather than guessing.

Source

Thrown at lib/crewai-tools/src/crewai_tools/tools/file_writer_tool/file_writer_tool.py:34

    """Coerce the spellings of true/false an LLM is likely to emit into a bool.

    Args:
        val: A bool, or one of y/yes/t/true/on/1 and n/no/f/false/off/0.

    Returns:
        The corresponding boolean.

    Raises:
        ValueError: If the string is not a recognized boolean spelling.
    """
    if isinstance(val, bool):
        return val
    val = val.lower()
    if val in ("y", "yes", "t", "true", "on", "1"):
        return True
    if val in ("n", "no", "f", "false", "off", "0"):
        return False
    raise ValueError(f"invalid value to cast to bool: {val!r}")


class FileWriterToolInput(BaseModel):
    """Input for FileWriterTool."""

    filename: str = Field(
        ...,
        description=(
            "Name of the file to write, relative to 'directory'. May include "
            "subdirectories, which are created if they do not exist."
        ),
    )
    content: str = Field(..., description="The text content to write to the file.")
    directory: str | None = Field(
        "./",
        description=(
            "Directory to write the file into. A relative path resolves inside "
            "the tool's allowed directory, and defaults to its root. Created if "

View on GitHub (pinned to 754d7323be)

Solutions

  1. Pass one of the accepted spellings: true/false, yes/no, y/n, t/f, on/off, 1/0 (case-insensitive).
  2. Strip whitespace on the caller side: val.strip().lower() before passing.
  3. Pass an actual Python bool instead of a string when calling programmatically (isinstance check short-circuits the parsing).

Example fix

# before
tool._run(filename='a.txt', content='hi', overwrite=' sure ')

# after
tool._run(filename='a.txt', content='hi', overwrite='yes')
Defensive patterns

Strategy: validation

Validate before calling

BOOL_TRUE = {'y','yes','t','true','on','1'}
BOOL_FALSE = {'n','no','f','false','off','0'}
def to_bool(val) -> bool:
    if isinstance(val, bool):
        return val
    v = str(val).strip().lower()
    if v in BOOL_TRUE: return True
    if v in BOOL_FALSE: return False
    raise ValueError(f'not a boolean: {val!r}')

Type guard

def is_bool_like(val) -> bool:
    return isinstance(val, bool) or str(val).strip().lower() in (
        {'y','yes','t','true','on','1'} | {'n','no','f','false','off','0'})

Try / catch

try:
    overwrite = to_bool(raw)
except ValueError:
    overwrite = False  # safe default for an overwrite flag
    logger.warning('unrecognized boolean %r, defaulting to False', raw)

Prevention

When it happens

Trigger: Passing a parameter that gets coerced through this helper with a value like 'maybe', '', '2', 'enabled', or 'Y/N' — anything outside the accepted spellings. Case is handled (input is lowercased) but surrounding whitespace or other text is not.

Common situations: An LLM agent answering a boolean flag with prose ('sure', 'nope'); a caller passing an int like 2 or -1; whitespace-padded input (' yes ') that fails exact matching after lower().

Related errors


AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15). Data as JSON: /api/errors/6e293f7e769c91f4. Report an issue: GitHub.