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

findings[{}].cvss_score must be between 0.0 and 10.0, got {}

Error message

findings[{}].cvss_score must be between 0.0 and 10.0, got {}

What it means

parse_vulnerability_json deserializes the report with serde, then enforces 0.0 <= findings[i].cvss_score <= 10.0 for every finding (vulnerability.rs:83-91). The index in the message identifies the offending finding. NaN also fails, because the range check is false for NaN.

Source

Thrown at crates/zeroclaw-runtime/src/security/vulnerability.rs:86

    }
}

pub fn parse_vulnerability_json(json_str: &str) -> anyhow::Result<VulnerabilityReport> {
    let report: VulnerabilityReport = serde_json::from_str(json_str).map_err(|e| {
        ::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!({"error": format!("{}", e)})),
            "vulnerability report rejected: JSON parse failed"
        );
        anyhow::Error::msg(format!("Failed to parse vulnerability report: {e}"))
    })?;

    for (i, finding) in report.findings.iter().enumerate() {
        if !(0.0..=10.0).contains(&finding.cvss_score) {
            anyhow::bail!(
                "findings[{}].cvss_score must be between 0.0 and 10.0, got {}",
                i,
                finding.cvss_score
            );
        }
    }

    Ok(report)
}

/// Generate a summary of the vulnerability report.
pub fn generate_summary(report: &VulnerabilityReport) -> String {
    if report.findings.is_empty() {
        return format!(
            "Vulnerability scan by {} on {}: No findings.",
            report.scanner,
            report.scan_date.format("%Y-%m-%d")
        );
    }

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Sanitize the source report: clamp or drop findings with sentinel scores before calling parse_vulnerability_json
  2. Fix the exporter so unknown scores are omitted or written as 0.0
  3. Pre-validate the findings array yourself if you accept untrusted scanner output

Example fix

// before
let report = parse_vulnerability_json(&raw)?;

// after: clamp sentinel scores before parsing
let mut value: serde_json::Value = serde_json::from_str(&raw)?;
if let Some(findings) = value.get_mut("findings").and_then(|f| f.as_array_mut()) {
    for f in findings {
        if let Some(score) = f.get("cvss_score").and_then(|s| s.as_f64()) {
            if !(0.0..=10.0).contains(&score) {
                f["cvss_score"] = serde_json::json!(score.clamp(0.0, 10.0));
            }
        }
    }
}
let report = parse_vulnerability_json(&value.to_string())?;
Defensive patterns

Strategy: validation

Validate before calling

fn cvss_scores_valid(json: &str) -> Result<(), String> {
    let v: serde_json::Value = serde_json::from_str(json).map_err(|e| e.to_string())?;
    let findings = v.get("findings").and_then(|f| f.as_array()).ok_or("missing findings")?;
    for (i, f) in findings.iter().enumerate() {
        let ok = f.get("cvss_score")
            .and_then(|s| s.as_f64())
            .map(|s| (0.0..=10.0).contains(&s))
            .unwrap_or(false);
        if !ok { return Err(format!("findings[{i}].cvss_score out of range")); }
    }
    Ok(())
}

Try / catch

Catch the error and parse the 'findings[{i}]' index from the message to report the exact offending finding to the scanner operator; do not retry the same input.

Prevention

When it happens

Trigger: Feeding a report where a finding has cvss_score -1 (a common 'unknown' sentinel), 99, or NaN; the message prints the exact array index and value.

Common situations: Scanner exporters write -1 for un-scored CVEs; a CSV-to-JSON converter mangles numeric fields; hand-edited report JSON with placeholder scores.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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