{"record":{"id":"3fe5f9faf0a4e13d","repo":"usestrix/strix","slug":"failed-to-calculate-cvss-for-validated-vector-ve","errorCode":null,"errorMessage":"Failed to calculate CVSS for validated vector: {vector}","messagePattern":"Failed to calculate CVSS for validated vector: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"strix/tools/reporting/tool.py","lineNumber":144,"sourceCode":"\n\ndef _calculate_cvss(breakdown: dict[str, str]) -> tuple[float, str, str]:\n    from cvss import CVSS3\n\n    vector = (\n        f\"CVSS:3.1/AV:{breakdown['attack_vector']}/AC:{breakdown['attack_complexity']}/\"\n        f\"PR:{breakdown['privileges_required']}/UI:{breakdown['user_interaction']}/\"\n        f\"S:{breakdown['scope']}/C:{breakdown['confidentiality']}/\"\n        f\"I:{breakdown['integrity']}/A:{breakdown['availability']}\"\n    )\n\n    try:\n        cvss = CVSS3(vector)\n        score = cvss.scores()[0]\n        base_severity = cvss.severities()[0].lower()\n    except Exception as exc:\n        msg = f\"Failed to calculate CVSS for validated vector: {vector}\"\n        raise ValueError(msg) from exc\n\n    severity = \"info\" if base_severity == \"none\" else base_severity\n    return score, severity, vector\n\n\n_REQUIRED_FIELDS = {\n    \"title\": \"Title cannot be empty\",\n    \"description\": \"Description cannot be empty\",\n    \"impact\": \"Impact cannot be empty\",\n    \"target\": \"Target cannot be empty\",\n    \"technical_analysis\": \"Technical analysis cannot be empty\",\n    \"poc_description\": \"PoC description cannot be empty\",\n    \"poc_script_code\": \"PoC script/code is REQUIRED - provide the actual exploit/payload\",\n    \"remediation_steps\": \"Remediation steps cannot be empty\",\n    \"evidence\": \"Evidence cannot be empty - provide concrete proof of the finding\",\n    \"assumptions\": \"Assumptions cannot be empty - state exploitability prerequisites\",\n}\n","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/usestrix/strix/blob/85513391305171ecc6faffe03da4a8bda5e3febb/strix/tools/reporting/tool.py#L126-L162","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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).","Fix the source breakdown (usually LLM output constrained by the reporting prompt/tool schema) and resubmit the finding.","Pin/align the cvss library version with what this Strix release was tested against.","If a specific metric value is legitimately unavailable, map it to the closest valid value before vector construction."],"exampleFix":"# before\nbreakdown = {\"attack_vector\": \"N\", \"privileges_required\": \"admin\", ...}\n# vector: .../PR:admin/... -> library raises\n\n# after\nbreakdown = {\"attack_vector\": \"N\", \"privileges_required\": \"H\", ...}\n# vector: .../PR:H/... -> valid CVSS:3.1","handlingStrategy":"try-catch","validationCode":"from cvss import CVSS3\n\ndef cvss_vector_computable(breakdown: dict) -> bool:\n    vector = (f\"CVSS:3.1/AV:{breakdown['attack_vector']}/AC:{breakdown['attack_complexity']}\"\n              f\"/PR:{breakdown['privileges_required']}/UI:{breakdown['user_interaction']}\"\n              f\"/S:{breakdown['scope']}/C:{breakdown['confidentiality']}\"\n              f\"/I:{breakdown['integrity']}/A:{breakdown['availability']}\")\n    try:\n        CVSS3(vector).scores()\n        return True\n    except Exception:\n        return False","typeGuard":"CVSS_ENUMS = {\n    \"attack_vector\": {\"N\", \"A\", \"L\", \"P\"}, \"attack_complexity\": {\"L\", \"H\"},\n    \"privileges_required\": {\"N\", \"L\", \"H\"}, \"user_interaction\": {\"N\", \"R\"},\n    \"scope\": {\"U\", \"C\"}, \"confidentiality\": {\"N\", \"L\", \"H\"},\n    \"integrity\": {\"N\", \"L\", \"H\"}, \"availability\": {\"N\", \"L\", \"H\"},\n}\n\ndef is_valid_breakdown(b: dict) -> bool:\n    return all(b.get(k) in vals for k, vals in CVSS_ENUMS.items())","tryCatchPattern":"try:\n    score, severity, vector = compute_cvss(breakdown)\nexcept ValueError as exc:\n    if \"Failed to calculate CVSS\" in str(exc):\n        breakdown = clamp_to_enums(breakdown)  # snap values to CVSS 3.1 domains\n        score, severity, vector = compute_cvss(breakdown)\n    else:\n        raise","preventionTips":["Constrain LLM output for CVSS fields to the exact CVSS 3.1 metric alphabets in the tool schema.","Pre-validate breakdowns against the metric enums before vector construction.","Pin the cvss library version; parser strictness changes across releases."],"tags":["cvss","reporting","validation","llm-output"],"backgroundTag":null,"analyzedSha":"85513391305171ecc6faffe03da4a8bda5e3febb","analyzedAt":"2026-08-15T05:03:57.275Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}