Skip to content

Inconsistent JSON output format when no checks are evaluated #7462

@daily-dreamer

Description

@daily-dreamer

name: Bug Report - Inconsistent JSON Output Format
about: JSON output format differs when no checks are evaluated
title: 'Inconsistent JSON output format when no checks are evaluated'
labels: bug, api, json-output
assignees: ''

Description

Checkov returns an inconsistent JSON output format when no checks are evaluated (empty directory, no matching resources, etc.). This makes it difficult for tools to parse the output reliably.

Current Behavior

When scanning an empty directory or when no checks match any resources, Checkov returns only the summary object:

{
    "passed": 0,
    "failed": 0,
    "skipped": 0,
    "parsing_errors": 0,
    "resource_count": 0,
    "checkov_version": "3.2.509"
}

Expected Behavior

The JSON output should maintain a consistent structure regardless of whether checks were evaluated:

{
    "check_type": "",
    "results": {
        "passed_checks": [],
        "failed_checks": [],
        "skipped_checks": [],
        "parsing_errors": []
    },
    "summary": {
        "passed": 0,
        "failed": 0,
        "skipped": 0,
        "parsing_errors": 0,
        "resource_count": 0,
        "checkov_version": "3.2.509"
    },
    "url": "Add an api key '--bc-api-key <api-key>' to see more detailed insights via https://bridgecrew.cloud"
}

Steps to Reproduce

  1. Create an empty directory:

    mkdir /tmp/empty_test
  2. Run Checkov with JSON output:

    checkov -d /tmp/empty_test --output json
  3. Observe the output format

  4. Compare with a directory that has resources:

    checkov -d /path/with/terraform/files --output json

Affected Scenarios

This inconsistency occurs in three main scenarios:

  1. File Not Present: Target path doesn't exist
  2. Nothing to Scan: File/directory exists but contains no recognizable resources (empty files, comments only)
  3. No Matches: Resources are found but no policies match those specific resources

Impact

For API Consumers

Tools integrating with Checkov must implement conditional parsing logic:

# Current workaround needed
result = json.loads(checkov_output)

# Check if it's the summary-only format
if "check_type" in result:
    # Standard format
    passed = result["summary"]["passed"]
else:
    # Summary-only format
    passed = result["passed"]

Real-World Use Cases Affected

  • CI/CD Pipelines: Scripts parsing Checkov output fail when format changes
  • Security Dashboards: Aggregation tools need special handling for empty results
  • Compliance Reports: Automated reporting breaks with inconsistent schemas
  • Monitoring Systems: Metrics collection requires conditional logic

Environment

  • Checkov Version: 3.2.509 (and earlier)
  • Python Version: 3.9+
  • Operating System: All platforms
  • Installation Method: pip, docker, binary

Root Cause

File: checkov/common/runners/runner_registry.py
Line: 535

When report_jsons list is empty, the code calls:

report_json_output = Report("").get_summary()

Instead of:

report_json_output = Report("").get_dict(...)

Proposed Solution

Change line 535 in runner_registry.py to use get_dict() instead of get_summary() to maintain format consistency.

Benefits

API Consistency: Same JSON schema for all responses
Easier Integration: No conditional parsing logic needed
Best Practices: Follows REST API standards
Better DX: Predictable schemas improve developer experience
Reduced Bugs: Eliminates integration issues from format changes

Potential Breaking Change

⚠️ Tools specifically parsing the summary-only format will need updates:

# Migration needed
# Old: result["passed"]
# New: result["summary"]["passed"]

However, this is a worthwhile breaking change because:

  • Fixes a design inconsistency
  • Aligns with REST API best practices
  • Makes future integrations easier
  • The summary is still available (nested under summary key)

Additional Context

This issue affects any tool or script that programmatically parses Checkov's JSON output. The inconsistency violates the principle of least surprise and makes Checkov harder to integrate with other tools.

Related Documentation

  • JSON output format should be documented consistently
  • API consumers should be able to rely on a stable schema
  • Empty results should follow the same structure as non-empty results

Checklist

  • I have searched for similar issues
  • I have provided steps to reproduce
  • I have included environment details
  • I have explained the impact
  • I have proposed a solution

Note: A fix for this issue is available in PR #7472

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions