Skip to content

fix(serverless): report unparsable serverless files as parsing errors - #7632

Open
Zuhef wants to merge 1 commit into
bridgecrewio:mainfrom
Zuhef:fix/alpha-serverless-parsing-errors
Open

fix(serverless): report unparsable serverless files as parsing errors#7632
Zuhef wants to merge 1 commit into
bridgecrewio:mainfrom
Zuhef:fix/alpha-serverless-parsing-errors

Conversation

@Zuhef

@Zuhef Zuhef commented Jul 30, 2026

Copy link
Copy Markdown

Description

A serverless.yml that fails to parse is dropped from the scan without appearing anywhere in the report, so a scan that examined nothing looks the same as a clean scan.

checkov/serverless/parsers/parser.py catches CfnParseError, logs a warning and returns None. serverless/utils.py::get_files_definitions then discards that None without recording anything, and serverless/runner.py never calls report.add_parsing_errors() — unlike the ARM, Bicep, CloudFormation and Terraform runners.

Reproducer — a serverless.yml whose provider tag value is a single = (valid YAML, but the loader has no constructor for the tag:yaml.org,2002:value it resolves to):

provider:
  name: aws
  tags:
    test: =
functions:
  hello:
    handler: handler.hello

Before:

$ checkov --framework serverless -f serverless.yml -o json --compact
[WARNI]  Failed to parse file serverless.yml because it isn't valid yaml
{ "passed": 0, "failed": 0, "parsing_errors": 0, "resource_count": 0, ... }
$ echo $?
0

After:

$ checkov --framework serverless -f serverless.yml -o json --compact
{
    "results": { ..., "parsing_errors": ["serverless.yml"] },
    "summary": { "passed": 0, "failed": 0, "parsing_errors": 1, ... }
}

$ CKV_PARSE_ERROR_FAIL=true checkov --framework serverless -f serverless.yml --compact
Passed checks: 0, Failed checks: 0, Skipped checks: 0, Parsing errors: 1
Error parsing file serverless.yml
$ echo $?
1

The warning was already logged, so this is not about visibility in a terminal — it is about the file being absent from the machine-readable report, which is what CI consumes, and about CKV_PARSE_ERROR_FAIL having nothing to act on.

Note serverless files are pre-filtered by SLS_FILE_MASK before parsing, so a parse failure here always means "a serverless file that could not be read", never "a file that belongs to another framework".

Fix

Follows the existing convention, with an optional out_parsing_errors argument so no caller signature breaks:

  • parsers/parser.py::parse records the error message for the file on CfnParseError.
  • _parallel_parse returns the errors it collected rather than writing to a shared mapping, because parsing goes through parallel_runner and may run in a separate process; get_files_definitions merges them for the caller.
  • runner.py passes a mapping down and calls report.add_parsing_errors(...), matching cloudformation/runner.py.

This is the same gap I fixed for the Kubernetes runner in #7630; serverless was the remaining one in that family. The two PRs are independent but share a rationale, so they may be easiest to review together.

Testing

$ python -m pytest tests/serverless -q
5 failed, 48 passed

Baseline on an unmodified checkout is 5 failed, 47 passed with the identical five failures — Windows-only path assertions in test_runner.py (test_record_relative_path_*) plus test_AdminPolicyDocument::test_summary. None are in the code touched here.

Added test_unparsable_file_is_reported_as_parsing_error, which asserts the file is listed in report.parsing_errors, that summary["parsing_errors"] == 1, that no checks are reported for it, and that get_exit_code returns 0 normally but 1 with CKV_PARSE_ERROR_FAIL set. It fails without the fix:

AssertionError: Lists differ: [] != ['...\\serverless.yml']

Also verified a valid serverless.yml is unaffected — still 3 passed, 0 parsing_errors.

  • flake8 checkov/serverless tests/serverless/runner/test_runner.py — clean.
  • mypy --config-file mypy.ini checkov/serverless — 6 errors before and after; comparing the two lists with line numbers stripped shows they are identical, so no new type errors.

A serverless.yml that fails to parse was dropped from the scan without appearing in the report, so parsing_errors stayed 0 and CKV_PARSE_ERROR_FAIL had nothing to act on. Collect the parse errors and add them to the report via add_parsing_errors, the same way the ARM, Bicep, CloudFormation and Terraform runners already do.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants