zeroclaw-labs/zeroclaw · error
providers.models.{profile_name}.pricing.{key}: value must be
Error message
providers.models.{profile_name}.pricing.{key}: value must be >= 0.0 (got {value}) What it means
In the same pricing-map loop as the NaN check, any value < 0.0 bails with the key and value printed. Negative prices corrupt cost accounting (they produce negative invoices) and almost always indicate a unit or sign mistake rather than intent. Both checks run per key, so a map with several bad values reports the first one.
Source
Thrown at crates/zeroclaw-config/src/schema.rs:21637
.with_attrs(::serde_json::json!({
"profile": profile_name,
"temperature": temp,
"error": format!("{}", e),
})),
"providers.models.<alias>.temperature rejected"
);
anyhow::Error::msg(format!("providers.models.{profile_name}.temperature: {e}"))
})?;
}
for (key, value) in &profile.pricing {
if value.is_nan() {
anyhow::bail!(
"providers.models.{profile_name}.pricing.{key}: value must not be NaN"
);
}
if *value < 0.0 {
anyhow::bail!(
"providers.models.{profile_name}.pricing.{key}: value must be >= 0.0 (got {value})"
);
}
}
}
// Non-fatal validation warnings: surfaced both via tracing (CLI sees
// on stderr) and via Config::collect_warnings (gateway HTTP returns
// structured to dashboard callers). Single source of truth lives in
// collect_warnings; emit each one to tracing here so the existing
// log behavior is preserved.
for w in self.collect_warnings() {
::zeroclaw_log::record!(
WARN,
::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Note)
.with_outcome(::zeroclaw_log::EventOutcome::Unknown)
.with_attrs(::serde_json::json!({"path": w.path, "code": w.code})),
&format!("{}", w.message)View on GitHub (pinned to 88bb9c8533)
Solutions
- Correct the sign of the named key
- Check unit scale: many vendors quote $/1M tokens — convert to the per-token figure the config expects before storing
- Clamp generated prices at 0.0 (pricing config generators should emit `v.max(0.0)`)
- Re-run validation to catch remaining keys — only the first failing key is reported per run
Example fix
# before [providers.models.gpt-x.pricing] input = -0.001 output = 0.002 # after [providers.models.gpt-x.pricing] input = 0.001 output = 0.002
Defensive patterns
Strategy: validation
Validate before calling
fn pricing_nonneg_precheck(cfg: &zeroclaw_config::Config) -> Result<(), String> {
for (name, profile) in &cfg.providers.models.entries {
for (key, value) in &profile.pricing {
if *value < 0.0 {
return Err(format!("providers.models.{name}.pricing.{key} = {value} < 0"));
}
}
}
Ok(())
} Type guard
fn pricing_is_nonnegative(pricing: &std::collections::HashMap<String, f64>) -> bool {
pricing.values().all(|v| *v >= 0.0)
} Try / catch
if let Err(err) = config.validate() {
if err.to_string().contains("must be >= 0.0") {
// fix the sign/unit of the named key (check $/1M vs per-token scale) and reload
}
} Prevention
- Convert vendor $/1M-token quotes to per-token before storing
- Clamp computed prices with v.max(0.0) in generators
- Review spreadsheet-copied values for stray minus signs
When it happens
Trigger: Set any pricing key to a negative number, e.g. `input = -0.001`, or generate pricing from arithmetic that underflows to a tiny negative value (per-1M to per-token conversion bugs).
Common situations: Transcribing vendor pricing sheets where credits/discounts are negative; spreadsheet copy-paste carrying minus signs; float arithmetic like `x/1000 - epsilon` producing -1e-19.
Related errors
- providers.models.{profile_name}.pricing.{key}: value must no
- providers.models.{profile_name}.uri must use http/https
- providers.models.ollama.{alias}.model uses ':cloud', but uri
- providers.models.ollama.{alias}.model uses ':cloud', but no
- cloud_ops.iac_tools must not be empty when cloud_ops is enab
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/4b0dfc97d4152411.
Report an issue: GitHub.