zeroclaw-labs/zeroclaw · error · anyhow::Error

Grok CLI model provider received a non-finite temperature va

Error message

Grok CLI model provider received a non-finite temperature value

What it means

validate_temperature rejects NaN and infinite temperatures before the Grok CLI process is started. The CLI has no sampling flag, so temperature is never forwarded; the check exists to catch garbage input early. Non-finite values typically enter through config deserialization (TOML/JSON accept `nan`/`inf` literals) or upstream arithmetic such as 0/0 or overflow in code that computes the value.

Source

Thrown at crates/zeroclaw-providers/src/grok_cli.rs:652

            index += 1;
        }
        policy
    }

    fn should_forward_model(model: &str) -> bool {
        let trimmed = model.trim();
        !trimmed.is_empty() && trimmed != DEFAULT_MODEL_MARKER
    }

    fn supports_temperature(temperature: f64) -> bool {
        GROK_CLI_SUPPORTED_TEMPERATURES
            .iter()
            .any(|value| (temperature - value).abs() < TEMP_EPSILON)
    }

    fn validate_temperature(temperature: f64) -> anyhow::Result<()> {
        if !temperature.is_finite() {
            anyhow::bail!("Grok CLI model provider received a non-finite temperature value");
        }
        if !Self::supports_temperature(temperature) {
            anyhow::bail!(
                "temperature unsupported by Grok CLI model provider: {temperature}. \
                 Supported values: 0.7 or 1.0 (not forwarded; CLI has no sampling flag)"
            );
        }
        Ok(())
    }

    /// Build the documented ACP invocation. Permission and tool overrides are
    /// accepted only through explicit per-alias `extra_args`.
    fn build_cli_args(model: &str, extra_args: &[String]) -> Vec<String> {
        let mut args = Vec::with_capacity(16 + extra_args.len());
        args.push("--no-auto-update".to_string());
        args.push("--no-plan".to_string());

        if !Self::extra_args_set_any(extra_args, &["--sandbox"]) {

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Guard the producer: check `is_finite()` on any computed temperature before passing it to chat
  2. Fix or delete the `temperature` entry in the agent/config file (deleting the key uses the provider default)
  3. Pass Some(0.7) or Some(1.0) explicitly — the only supported values for grok_cli

Example fix

// before
let temp = normalize(score) / count; // NaN when count == 0
provider.chat(req, model, Some(temp)).await?;

// after
let temp = if temp.is_finite() { temp } else { 0.7 };
provider.chat(req, model, Some(temp)).await?;
Defensive patterns

Strategy: validation

Validate before calling

fn temperature_safe(t: Option<f64>) -> bool {
    t.map(f64::is_finite).unwrap_or(true)
}

Type guard

fn is_finite_temperature(t: f64) -> bool { t.is_finite() }

Try / catch

let temp = computed.filter(|t| t.is_finite());
if let Err(e) = provider.chat(req, model, temp).await {
    if e.to_string().contains("non-finite temperature") {
        // producer bug: audit upstream math instead of retrying
    }
}

Prevention

When it happens

Trigger: A chat call on a grok_cli provider with temperature = NaN or +/-inf: `temperature = nan` in a config file, a computed `Some(x / count)` where count == 0, or lenient f64 parsing of the string "NaN".

Common situations: Agent profiles with hand-edited temperature fields; normalization or decay math upstream that divides by zero without guarding; JSON payloads where a missing value was coerced to NaN.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/080ba6191d8ab0d3. Report an issue: GitHub.