Hmbown/CodeWhale · error
Burn rate must be at least $0.01/hr.
Error message
Burn rate must be at least $0.01/hr.
What it means
After rounding to cents, a burn rate of 0 or less is rejected. A sub-cent rate (e.g. 0.005) rounds to $0/hr, which the pace governor would treat as an unbounded rate, silently dropping the requested cap — so the library refuses it instead.
Solutions
- Use a burn rate of at least 0.01 $/hr
- Round or clamp the value up to $0.01/hr before parsing
- If a near-zero cap is intended, disable the burn rate instead of passing a sub-cent value
Example fix
// before burn_rate: 0.004 // after burn_rate: 0.01
Defensive patterns
Strategy: validation
Validate before calling
fn burn_rate_ok(v: f64) -> bool { v.is_finite() && ((v * 100.0).round() / 100.0) >= 0.01 } Try / catch
match parse_burn_rate(input) { Err(e) if e.to_string().contains("$0.01") => eprintln!("rate too small: {}", e), Ok(v) => apply(v), Err(e) => return Err(e), } Prevention
- Round sub-cent rates up to 0.01 instead of down
- Treat burn rate granularity as cents everywhere
- Disable the cap explicitly rather than passing ~0
When it happens
Trigger: Calling parse_burn_amount (via parse_burn_rate or normalize_burn_rate) with a positive but sub-$0.01 amount such as 0.001, or a value that rounds down to 0.
Common situations: Entering an intentionally tiny burn rate in config; unit confusion (entering fractions of a dollar); floating-point values below the cent granularity.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- agent profile provider cannot be empty
- agent profile provider must be a simple provider id
- api_key cannot be empty string
- approval_policy ' ' is not allowed by requirements ( )
- budget document_kind must be
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/9d4d08d52851f017.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/operate.rs:282
.or_else(|| value.as_str().and_then(|s| s.parse().ok()))
}
fn parse_burn_amount(amount: Option<f64>) -> Result<Option<OperateBurnRate>> {
let Some(amount) = amount else {
return Ok(None);
};
if !amount.is_finite() || amount <= 0.0 {
anyhow::bail!("Burn rate is optional. When set, it must be a positive $/hr.");
}
if amount > 10_000.0 {
anyhow::bail!("Burn rate must be 10000 $/hr or less.");
}
let rounded = (amount * 100.0).round() / 100.0;
if rounded <= 0.0 {
// A sub-cent rate rounds to a $0/hr target, which the pace governor
// would treat as unbounded — reject it instead of silently dropping
// the requested cap.
anyhow::bail!("Burn rate must be at least $0.01/hr.");
}
Ok(Some(OperateBurnRate {
kind: "usd_per_hour".to_string(),
amount_usd_per_hour: rounded,
}))
}
fn derive_status(op: &Operation) -> (OperateStatus, Option<OperateIdleReason>) {
if op.status == OperateStatus::Cancelled {
return (OperateStatus::Cancelled, None);
}
if !op.credentials_present {
return (
OperateStatus::IdleBlocked,
Some(OperateIdleReason::MissingCredentials),
);
}
if op.direction.is_empty() {View on GitHub (pinned to 73e0f67d83)