zeroclaw-labs/zeroclaw · error
Estimated cost must be a finite, non-negative value
Error message
Estimated cost must be a finite, non-negative value
What it means
CostTracker::check_budget validates the per-call cost estimate before comparing it against daily and monthly spending limits, rejecting NaN, infinity, and negative values. The guard exists because one non-finite float would poison every subsequent comparison and render all budget limits meaningless. The rejection is logged as a WARN Reject event carrying the offending estimated_cost_usd attribute.
Source
Thrown at crates/zeroclaw-config/src/cost/tracker.rs:109
self.lock_storage().path.clone()
}
/// Check if a request is within budget.
pub fn check_budget(&self, estimated_cost_usd: f64) -> Result<BudgetCheck> {
let config = self.config_snapshot();
if !config.enabled {
return Ok(BudgetCheck::Allowed);
}
if !estimated_cost_usd.is_finite() || estimated_cost_usd < 0.0 {
::zeroclaw_log::record!(
WARN,
::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Reject)
.with_outcome(::zeroclaw_log::EventOutcome::Failure)
.with_attrs(::serde_json::json!({"estimated_cost_usd": estimated_cost_usd})),
"cost budget check rejected: estimated cost is not finite or is negative"
);
anyhow::bail!("Estimated cost must be a finite, non-negative value");
}
let mut storage = self.lock_storage();
let (daily_cost, monthly_cost) = storage.get_aggregated_costs()?;
// Check daily limit
let projected_daily = daily_cost + estimated_cost_usd;
if projected_daily > config.daily_limit_usd {
return Ok(BudgetCheck::Exceeded {
current_usd: daily_cost,
limit_usd: config.daily_limit_usd,
period: UsagePeriod::Day,
});
}
// Check monthly limit
let projected_monthly = monthly_cost + estimated_cost_usd;
if projected_monthly > config.monthly_limit_usd {View on GitHub (pinned to 88bb9c8533)
Solutions
- Trace the inputs: log the model price and token counts that produced the estimate before calling check_budget
- Default missing/unparseable prices to 0.0 instead of letting NaN propagate
- Guard the call site: skip or zero the estimate when `!c.is_finite() || c < 0.0`
- Add a unit test with the exact pricing data that produced the bad value to lock the fix in
Example fix
// before
let check = tracker.check_budget(estimated)?; // panics path on NaN
// after
let estimated = if estimated.is_finite() && estimated >= 0.0 { estimated } else { 0.0 };
let check = tracker.check_budget(estimated)?; Defensive patterns
Strategy: validation
Validate before calling
fn sanitize_cost(c: f64) -> f64 {
if c.is_finite() && c >= 0.0 { c } else { 0.0 }
}
let estimate = sanitize_cost(estimate);
let check = tracker.check_budget(estimate)?; Type guard
fn is_valid_cost(c: f64) -> bool {
c.is_finite() && c >= 0.0
} Try / catch
match tracker.check_budget(estimate) {
Ok(check) => Ok(check),
Err(e) if !estimate.is_finite() || estimate < 0.0 => {
tracing::error!(estimate, "bad cost estimate; treating as 0");
tracker.check_budget(0.0)
}
Err(e) => Err(e),
} Prevention
- Never unwrap Option<f64> prices into arithmetic — default to 0.0 and log the missing model
- Unit-test cost math with missing-price and zero-token inputs
- Assert is_valid_cost on every value crossing into CostTracker
When it happens
Trigger: Calling `check_budget(estimated_cost_usd)` where the estimate came from math on a missing or unparsed model price (NaN propagates through arithmetic), or where a subtraction bug produced a negative number. Tests invalid_budget_estimate_is_rejected and check_tool_loop_budget pin this behavior.
Common situations: The provider pricing table has no entry for the active model so cost math yields NaN; a price string fails to parse and the error path leaks into the estimate; tool-loop estimates go negative after refunds or discount subtractions.
Related errors
- Token usage cost must be a finite, non-negative value
- Gemini CLI model_provider received non-finite temperature va
- Grok CLI model provider received a non-finite temperature va
- KiloCLI model_provider received non-finite temperature value
- effective cost limit must be a non-negative finite value
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/ec819c1dc49aaddd.
Report an issue: GitHub.