usestrix/strix · error · ValueError

Failed to calculate CVSS for validated vector: {vector}

Error message

Failed to calculate CVSS for validated vector: {vector}

What it means

The reporting tool builds a CVSS:3.1 vector from a breakdown, wraps cvss-lib's CVSS3(vector), and calls scores()/severities(). If the library throws even for a vector that passed earlier validation, it re-raises as ValueError('Failed to calculate CVSS for validated vector: ...') with the original exception chained. The message includes the exact vector for diagnosis.

Source

Thrown at strix/tools/reporting/tool.py:144


def _calculate_cvss(breakdown: dict[str, str]) -> tuple[float, str, str]:
    from cvss import CVSS3

    vector = (
        f"CVSS:3.1/AV:{breakdown['attack_vector']}/AC:{breakdown['attack_complexity']}/"
        f"PR:{breakdown['privileges_required']}/UI:{breakdown['user_interaction']}/"
        f"S:{breakdown['scope']}/C:{breakdown['confidentiality']}/"
        f"I:{breakdown['integrity']}/A:{breakdown['availability']}"
    )

    try:
        cvss = CVSS3(vector)
        score = cvss.scores()[0]
        base_severity = cvss.severities()[0].lower()
    except Exception as exc:
        msg = f"Failed to calculate CVSS for validated vector: {vector}"
        raise ValueError(msg) from exc

    severity = "info" if base_severity == "none" else base_severity
    return score, severity, vector


_REQUIRED_FIELDS = {
    "title": "Title cannot be empty",
    "description": "Description cannot be empty",
    "impact": "Impact cannot be empty",
    "target": "Target cannot be empty",
    "technical_analysis": "Technical analysis cannot be empty",
    "poc_description": "PoC description cannot be empty",
    "poc_script_code": "PoC script/code is REQUIRED - provide the actual exploit/payload",
    "remediation_steps": "Remediation steps cannot be empty",
    "evidence": "Evidence cannot be empty - provide concrete proof of the finding",
    "assumptions": "Assumptions cannot be empty - state exploitability prerequisites",
}

View on GitHub (pinned to 8551339130)

Solutions

  1. Inspect the vector in the error message and compare each metric against the CVSS 3.1 spec (AV:N|A|L|P, AC:L|H, PR:N|L|H, UI:N|R, S:U|C, C/I/A:N|L|H).
  2. Fix the source breakdown (usually LLM output constrained by the reporting prompt/tool schema) and resubmit the finding.
  3. Pin/align the cvss library version with what this Strix release was tested against.
  4. If a specific metric value is legitimately unavailable, map it to the closest valid value before vector construction.

Example fix

# before
breakdown = {"attack_vector": "N", "privileges_required": "admin", ...}
# vector: .../PR:admin/... -> library raises

# after
breakdown = {"attack_vector": "N", "privileges_required": "H", ...}
# vector: .../PR:H/... -> valid CVSS:3.1
Defensive patterns

Strategy: try-catch

Validate before calling

from cvss import CVSS3

def cvss_vector_computable(breakdown: dict) -> bool:
    vector = (f"CVSS:3.1/AV:{breakdown['attack_vector']}/AC:{breakdown['attack_complexity']}"
              f"/PR:{breakdown['privileges_required']}/UI:{breakdown['user_interaction']}"
              f"/S:{breakdown['scope']}/C:{breakdown['confidentiality']}"
              f"/I:{breakdown['integrity']}/A:{breakdown['availability']}")
    try:
        CVSS3(vector).scores()
        return True
    except Exception:
        return False

Type guard

CVSS_ENUMS = {
    "attack_vector": {"N", "A", "L", "P"}, "attack_complexity": {"L", "H"},
    "privileges_required": {"N", "L", "H"}, "user_interaction": {"N", "R"},
    "scope": {"U", "C"}, "confidentiality": {"N", "L", "H"},
    "integrity": {"N", "L", "H"}, "availability": {"N", "L", "H"},
}

def is_valid_breakdown(b: dict) -> bool:
    return all(b.get(k) in vals for k, vals in CVSS_ENUMS.items())

Try / catch

try:
    score, severity, vector = compute_cvss(breakdown)
except ValueError as exc:
    if "Failed to calculate CVSS" in str(exc):
        breakdown = clamp_to_enums(breakdown)  # snap values to CVSS 3.1 domains
        score, severity, vector = compute_cvss(breakdown)
    else:
        raise

Prevention

When it happens

Trigger: A breakdown that string-formats into a syntactically plausible but semantically invalid CVSS:3.1 vector — e.g. an out-of-domain value like PR:admin, S:P combined with metrics the library rejects, or a library version whose parser is stricter than the upstream validator.

Common situations: LLM-generated vulnerability breakdowns with non-canonical metric values; cvss library major-version change tightening parsing; locale/case issues if values weren't normalized before formatting.

Related errors


AI-assisted analysis of usestrix/strix@8551339130 (2026-08-15). Data as JSON: /api/errors/3fe5f9faf0a4e13d. Report an issue: GitHub.