Hmbown/CodeWhale · error
Burn rate is optional. When set, it must be a positive $/hr.
Error message
Burn rate is optional. When set, it must be a positive $/hr.
What it means
`parse_burn_rate` parses a burn-rate value out of an operate patch JSON. Burn rate itself is optional, but if the incoming JSON provides none of the recognized keys (`usdPerHour`, `amount`, or the primary key), the value is treated as `None` and rejected: providing the field in a way that resolves to nothing is invalid. The message states the contract — optional, but positive $/hr when present.
Solutions
- Either omit the burn-rate field entirely (it is optional) or supply a positive numeric value under a recognized key (`usdPerHour` / `amount`).
- Fix the payload key name so the number lands under `usdPerHour` or `amount`.
- If you intended zero, remove the field — zero is not accepted either.
Example fix
// before
{"burnRate": {}}
// after
{"burnRate": {"usdPerHour": 5.0}}
// or remove the field entirely Defensive patterns
Strategy: validation
Validate before calling
fn burn_rate_payload_ok(v: &serde_json::Value) -> bool {
let obj = match v.get("burnRate") { Some(o) => o, None => return true }; // optional
obj.get("usdPerHour").or_else(|| obj.get("amount"))
.map(|n| n.as_f64().map_or(false, |x| x.is_finite() && x > 0.0))
.unwrap_or(false)
} Try / catch
match parse_burn_rate(&patch) {
Err(e) if e.to_string().contains("Burn rate is optional") => {
// drop or correct the burnRate field and resubmit
}
other => other,
} Prevention
- Omit burnRate entirely when unknown; never send an empty object or null.
- Always put the number under `usdPerHour` or `amount`.
- Validate patch JSON shape before applying.
When it happens
Trigger: Calling `parse_burn_rate` (via `apply_operate_patch` or tests) with a JSON object that has a burn-rate field present but with no recognizable amount key, so `amount` is `None` — e.g. `"burnRate": {}` or `"burnRate": null` explicitly supplied.
Common situations: Hand-writing an operate patch with an empty or null burn-rate object; a UI sending `usdPerHour` under a wrong key name the parser doesn't know; API version drift where the payload key changed.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Cargo metadata dependencies for
- Cargo metadata must contain workspace_members and packages…
- Cargo metadata root must be an object
- .annotations is not a valid MCP annotations object
- .size must be an integer
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/06e9ee437365003a.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/operate.rs:255
{
return Ok(None);
}
if let Some("unbounded") = value.get("kind").and_then(|kind| kind.as_str()) {
return Ok(None);
}
let amount = if value.is_number() || value.is_string() {
json_number(value)
} else {
json_number(
value
.get("amountUsdPerHour")
.or_else(|| value.get("usdPerHour"))
.or_else(|| value.get("amount"))
.unwrap_or(&serde_json::Value::Null),
)
};
if amount.is_none() {
anyhow::bail!("Burn rate is optional. When set, it must be a positive $/hr.");
}
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.");
}View on GitHub (pinned to 73e0f67d83)