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

temperature unsupported by KiloCLI: {temperature}. Supported

Error message

temperature unsupported by KiloCLI: {temperature}. Supported values: 0.7 or 1.0

What it means

KiloCLI accepts only temperature 0.7 and 1.0 (within TEMP_EPSILON); the CLI has no sampling flag, so these are validated no-ops and every other finite value fails per request. The message includes the rejected value so the offending profile is easy to find.

Source

Thrown at crates/zeroclaw-providers/src/kilocli.rs:92

    /// Returns true if the model argument should be forwarded to the CLI.
    fn should_forward_model(model: &str) -> bool {
        let trimmed = model.trim();
        !trimmed.is_empty() && trimmed != DEFAULT_MODEL_MARKER
    }

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

    fn validate_temperature(temperature: f64) -> anyhow::Result<()> {
        if !temperature.is_finite() {
            anyhow::bail!("KiloCLI model_provider received non-finite temperature value");
        }
        if !Self::supports_temperature(temperature) {
            anyhow::bail!(
                "temperature unsupported by KiloCLI: {temperature}. \
                 Supported values: 0.7 or 1.0"
            );
        }
        Ok(())
    }

    fn redact_stderr(stderr: &[u8]) -> String {
        let text = String::from_utf8_lossy(stderr);
        let trimmed = text.trim();
        if trimmed.is_empty() {
            return String::new();
        }
        if trimmed.chars().count() <= MAX_KILO_CLI_STDERR_CHARS {
            return trimmed.to_string();
        }
        let clipped: String = trimmed.chars().take(MAX_KILO_CLI_STDERR_CHARS).collect();
        format!("{clipped}...")

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Set temperature to 0.7 or 1.0, or omit the field
  2. Drop temperature overrides on agents bound to kilocli
  3. Use an API-based provider if you need arbitrary sampling values

Example fix

# before
[agents.helper]
model_provider = "kilocli"
temperature = 0.4

# after
[agents.helper]
model_provider = "kilocli"
temperature = 1.0
Defensive patterns

Strategy: validation

Validate before calling

fn kilo_temperature_ok(t: Option<f64>) -> bool {
    t.map(|v| (v - 0.7).abs() < 1e-9 || (v - 1.0).abs() < 1e-9).unwrap_or(true)
}

Type guard

fn is_supported_kilo_temperature(t: f64) -> bool {
    (t - 0.7).abs() < 1e-9 || (t - 1.0).abs() < 1e-9
}

Try / catch

match kilo.chat(req, model, temp).await {
    Err(e) if e.to_string().contains("temperature unsupported by KiloCLI") =>
        kilo.chat(req, model, Some(0.7)).await,
    other => other,
}

Prevention

When it happens

Trigger: chat_with_system/chat on a kilocli provider with temperature = 0.0, 0.5, 1.2, etc.; copying an agent block written for an HTTP provider that accepts arbitrary floats.

Common situations: Reusing tuned agent profiles after switching model_provider to kilocli; global temperature settings applied to all providers; experimentation scripts that sweep values.

Related errors


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