{"record":{"id":"c25b8328b9ee0b1a","repo":"Hmbown/CodeWhale","slug":"burn-rate-must-be-10000-hr-or-less","errorCode":null,"errorMessage":"Burn rate must be 10000 $/hr or less.","messagePattern":"Burn rate must be 10000 \\$/hr or less\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/operate.rs","lineNumber":275,"sourceCode":"    parse_burn_amount(amount)\n}\n\nfn json_number(value: &serde_json::Value) -> Option<f64> {\n    value\n        .as_f64()\n        .or_else(|| value.as_i64().map(|n| n as f64))\n        .or_else(|| value.as_str().and_then(|s| s.parse().ok()))\n}\n\nfn parse_burn_amount(amount: Option<f64>) -> Result<Option<OperateBurnRate>> {\n    let Some(amount) = amount else {\n        return Ok(None);\n    };\n    if !amount.is_finite() || amount <= 0.0 {\n        anyhow::bail!(\"Burn rate is optional. When set, it must be a positive $/hr.\");\n    }\n    if amount > 10_000.0 {\n        anyhow::bail!(\"Burn rate must be 10000 $/hr or less.\");\n    }\n    let rounded = (amount * 100.0).round() / 100.0;\n    if rounded <= 0.0 {\n        // A sub-cent rate rounds to a $0/hr target, which the pace governor\n        // would treat as unbounded — reject it instead of silently dropping\n        // the requested cap.\n        anyhow::bail!(\"Burn rate must be at least $0.01/hr.\");\n    }\n    Ok(Some(OperateBurnRate {\n        kind: \"usd_per_hour\".to_string(),\n        amount_usd_per_hour: rounded,\n    }))\n}\n\nfn derive_status(op: &Operation) -> (OperateStatus, Option<OperateIdleReason>) {\n    if op.status == OperateStatus::Cancelled {\n        return (OperateStatus::Cancelled, None);\n    }","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/operate.rs#L257-L293","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Lower the burn rate to a value <= 10000 $/hr","Check the unit: the value is dollars per hour, so divide per-minute or per-second figures accordingly","Clamp programmatically supplied amounts with amount.min(10_000.0) before calling parse"],"exampleFix":"// before\nburn_rate: 25000.0\n// after\nburn_rate: 2500.0","handlingStrategy":"validation","validationCode":"fn burn_rate_ok(v: f64) -> bool { v.is_finite() && v > 0.0 && v <= 10_000.0 }","typeGuard":null,"tryCatchPattern":"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), }","preventionTips":["Clamp computed rates with .min(10_000.0) before parsing","Keep the unit ($/hr) in the config field name or UI label","Add a config-load-time range check for burn rate"],"tags":["validation","range-check","config"],"backgroundTag":"value-out-of-range","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T06:17:15.046Z"}