Hmbown/CodeWhale · error
Failed to update setting: invalid max history
Error message
Failed to update setting: invalid max history '{value}'. Expected a positive number. What it means
Settings::set parses the `max_history`/`history` value as usize via str::parse; a parse failure produces this error. The message says 'positive number' though the type also accepts 0 — only non-numeric (or, on some platforms, overflowingly large) strings fail.
Solutions
- Pass a plain non-negative integer with no units or separators, e.g. `100`.
- Strip whitespace; str::parse does not trim trailing text.
- On 32-bit builds, keep the value within u32 range to avoid overflow rejections.
Example fix
// before
settings.set("max_history", "10,000")?;
// after
settings.set("max_history", "10000")?; Defensive patterns
Strategy: validation
Validate before calling
fn valid_max_history(v: &str) -> bool {
v.trim().parse::<usize>().is_ok()
} Try / catch
match value.trim().parse::<usize>() {
Ok(n) => settings.set("max_history", &n.to_string())?,
Err(_) => eprintln!("max_history must be a plain positive integer"),
} Prevention
- Parse numeric user input in the wrapper first; reject units and separators.
- Serialize numbers with .to_string(), never locale formatting.
- Clamp values in your UI before writing.
When it happens
Trigger: Settings::set("max_history", v) where v is not a valid usize literal — e.g. `history fifty`, `history 1000 entries`, `history -5`, or a value exceeding usize::MAX on 32-bit targets.
Common situations: Scripted /config commands passing prose or units ('5000 lines'), locales formatting numbers with separators ('10,000'), or negative numbers.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- A pinned task provider requires an explicit model
- approval log has no parent
- cannot parse exactly one Rust TRUSTED_KEYS table
- Could not parse destination route; contents omitted
- could not parse match block after
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/4d841430392fdefe.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/settings.rs:1738
"Failed to update setting: invalid cost currency '{value}'. Expected: usd, cny, rmb, yuan."
);
};
self.cost_currency = match currency {
crate::pricing::CostCurrency::Usd => "usd",
crate::pricing::CostCurrency::Cny => "cny",
}
.to_string();
}
"max_history" | "history" => {
let max: usize = value.parse().map_err(|_| {
anyhow::anyhow!(
"Failed to update setting: invalid max history '{value}'. Expected a positive number."
)
})?;
self.max_input_history = max;
}
"default_model" | "model" => {
anyhow::bail!(
"Model defaults belong to config.toml. Use /model and choose Remember as my default, or /config model <id> --save."
);
}
"reasoning_effort" | "effort" => {
self.reasoning_effort = normalize_reasoning_effort_setting(value)?;
}
"permission_posture" | "permissions" => {
self.permission_posture = normalize_permission_posture(value);
if self.permission_posture.is_none() {
anyhow::bail!(
"Failed to update setting: invalid permission posture '{value}'. Expected: ask, auto-review, or full-access."
);
}
}
"sandbox_mode" | "sandbox" | "filesystem_sandbox" => {
self.sandbox_mode = normalize_sandbox_mode(value);
if self.sandbox_mode.is_none() {
anyhow::bail!(View on GitHub (pinned to 73e0f67d83)