Hmbown/CodeWhale · error

Burn rate must be 10000 $/hr or less.

Error message

Burn rate must be 10000 $/hr or less.

What it means

parse_burn_amount validates the user-supplied operate burn rate cap. It only accepts finite, positive dollar-per-hour amounts, and caps them at $10,000/hr because the pace governor is calibrated to at most that rate. This error means the configured cap exceeds the supported ceiling.

Solutions

  1. Lower the burn rate to a value <= 10000 $/hr
  2. Check the unit: the value is dollars per hour, so divide per-minute or per-second figures accordingly
  3. Clamp programmatically supplied amounts with amount.min(10_000.0) before calling parse

Example fix

// before
burn_rate: 25000.0
// after
burn_rate: 2500.0
Defensive patterns

Strategy: validation

Validate before calling

fn burn_rate_ok(v: f64) -> bool { v.is_finite() && v > 0.0 && v <= 10_000.0 }

Try / catch

match parse_burn_rate(input) { Err(e) if e.to_string().contains("10000") => eprintln!("cap too high: {}", e), Ok(v) => apply(v), Err(e) => return Err(e), }

Prevention

When it happens

Trigger: Calling normalize_burn_rate or parse_burn_rate with a burn amount > 10,000 (e.g. a typo like 100000 in an operate config or slash command), or a non-clamped computed rate being passed in for normalization.

Common situations: Typing an extra zero in a burn-rate config field; misinterpreting the unit (e.g. entering cents or a per-minute rate so the number exceeds 10000); programmatically computing a rate without clamping.

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


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/c25b8328b9ee0b1a. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/operate.rs:275

    parse_burn_amount(amount)
}

fn json_number(value: &serde_json::Value) -> Option<f64> {
    value
        .as_f64()
        .or_else(|| value.as_i64().map(|n| n as f64))
        .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);
    }

View on GitHub (pinned to 73e0f67d83)