Hmbown/CodeWhale · error

Failed to parse boolean '{value}': expected on/off, true/fal

Error message

Failed to parse boolean '{value}': expected on/off, true/false, yes/no.

What it means

Thrown by parse_bool in the TUI settings update path (crates/tui/src/settings.rs). Boolean ':set' values are normalized through a fixed accept-list: on/true/yes/1/enabled map to true and off/false/no/0/disabled map to false, case-insensitively. Any other string bails with this message. Note the message only advertises on/off, true/false, yes/no even though 1/0/enabled/disabled are also accepted.

Source

Thrown at crates/tui/src/settings.rs:2559

            trimmed.to_ascii_lowercase().as_str(),
            "default" | "(default)" | "config" | "configured" | "unset"
        )
    {
        return Ok(None);
    }

    ReasoningEffort::parse_strict(trimmed)
        .map(|effort| Some(effort.as_setting().to_string()))
        .map_err(|err| anyhow::anyhow!("Failed to update setting: {err}"))
}

/// Parse a boolean value from various formats
fn parse_bool(value: &str) -> Result<bool> {
    match value.to_lowercase().as_str() {
        "on" | "true" | "yes" | "1" | "enabled" => Ok(true),
        "off" | "false" | "no" | "0" | "disabled" => Ok(false),
        _ => {
            anyhow::bail!("Failed to parse boolean '{value}': expected on/off, true/false, yes/no.")
        }
    }
}

fn default_thinking_preview_lines() -> usize {
    2
}

fn default_true() -> bool {
    true
}

fn parse_usize_setting(key: &str, value: &str) -> Result<usize> {
    value.trim().parse::<usize>().map_err(|_| {
        anyhow::anyhow!(
            "Failed to update setting: invalid {key} '{value}'. Expected 0 or a positive integer."
        )
    })

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Retry with an accepted literal: on, off, true, false, yes, no, 1, 0, enabled, or disabled (case-insensitive).
  2. If you typed 'enable'/'disable', use the past forms 'enabled'/'disabled'.
  3. Confirm the key is actually boolean; numeric and enum keys route through different parsers with their own accepted values.
  4. For wrappers, pre-validate the value against the accept-list before issuing the set command.

Example fix

# before
:set auto_compact enable

# after
:set auto_compact enabled
Defensive patterns

Strategy: validation

Validate before calling

fn is_accepted_bool(v: &str) -> bool {
    matches!(
        v.trim().to_lowercase().as_str(),
        "on" | "true" | "yes" | "1" | "enabled"
            | "off" | "false" | "no" | "0" | "disabled"
    )
}

if !is_accepted_bool(&value) {
    eprintln!("'{value}' is not an accepted boolean literal");
    return;
}

Try / catch

match update_setting(&key, &value) {
    Err(err) if err.to_string().contains("Failed to parse boolean") => {
        // show accepted literals, keep the session alive
    }
    other => other,
}

Prevention

When it happens

Trigger: Running ':set <boolean-key> <value>' with a value outside the accept-list, e.g. ':set streaming enable', ':set streaming 2', ':set streaming y', or ':set streaming toggle'. Any settings-update API that routes string values through parse_bool hits the same guard.

Common situations: Users abbreviate flags ('enable' instead of 'enabled', 'y'/'n'), pass numbers other than 0/1, or paste values with stray characters. Scripts that drive settings programmatically assume looser boolean parsing than this strict list allows.

Understand the failure class

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/2eb416195f55ffa5. Report an issue: GitHub.