Skip to content

fix: raise SchemaPatchError instead of exiting from schema patching - #4911

Merged
kddejong merged 1 commit into
aws-cloudformation:mainfrom
hoganbr-amzn:fix/schema-patch-raises
Oct 30, 2026
Merged

kddejong merged 1 commit into
aws-cloudformation:mainfrom
hoganbr-amzn:fix/schema-patch-raises

Conversation

@hoganbr-amzn

@hoganbr-amzn hoganbr-amzn commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Issue #, if available: fixes #4950

Description of changes:

ProviderSchemaManager.patch, OtherSchemaManager.patch and cfnlint.schema.patch called sys.exit(1) when a JSON patch failed to apply or an override spec could not be read. From a library caller that terminates the host process from inside a schema call.

They now raise SchemaPatchError, a CfnLintExitException with exit code 1. Runner.__init__ is where the override spec is applied, so main() catches CfnLintExitException around Runner(config), logs the message and exits with the same code, the way Runner.cli() already handles that exception. For an unreadable or malformed override spec the CLI output is unchanged (one line on stderr, exit 1); a patch that fails to apply, which was printed to stdout before, is now reported on stderr with the other errors. One behaviour change beyond the exception type: an IOError with an errno other than 2, 13 or 21 was previously swallowed and linting continued without the override spec; it now raises like the others. The existing tests that asserted SystemExit now assert the exception; new tests cover the previously swallowed errno and run main() with a missing --override-spec to check the exit code and logged message.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

PROVIDER_SCHEMA_MANAGER.patch, OTHER_SCHEMA_MANAGER.patch and
cfnlint.schema.patch called sys.exit(1) on a patch that failed to apply or
an override spec that could not be read, which terminates any process that
embeds cfn-lint as a library. Raise SchemaPatchError (a CfnLintExitException
with exit code 1) instead and let main() log it and exit with the same code,
as Runner.cli() already does for CfnLintExitException.

An IOError with an errno other than 2, 13 or 21 was previously swallowed and
linting continued without the override spec; it now raises like the others.

Signed-off-by: Brenden Hogan <hoganbr@amazon.com>
@kddejong
kddejong force-pushed the fix/schema-patch-raises branch from 83e7cd5 to 46df4be Compare October 30, 2026 20:44
@codecov

codecov Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.73%. Comparing base (5d5eddc) to head (46df4be).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4911      +/-   ##
==========================================
+ Coverage   94.72%   94.73%   +0.01%     
==========================================
  Files         442      442              
  Lines       16089    16088       -1     
  Branches     3121     3121              
==========================================
+ Hits        15240    15241       +1     
+ Misses        468      467       -1     
+ Partials      381      380       -1     
Flag Coverage Δ
unittests 94.72% <100.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@kddejong
kddejong merged commit b3bc127 into aws-cloudformation:main Oct 30, 2026
24 checks passed
kddejong added a commit to kddejong/cfn-python-lint that referenced this pull request Oct 30, 2026
Runner.__init__ reported an unresolvable --template glob by calling
_cli_output, which ends in sys.exit. Constructing a Runner therefore
terminated any process that embeds cfn-lint as a library, four lines above
the schema patching that aws-cloudformation#4911 fixed for the same reason. cfnlint.api
lint(), lint_file() and lint_by_config() all died the same way.

Record the error during construction and report it from cli() through the
unchanged _cli_output path, so the CLI keeps its exit code and byte-level
output for every --format, and raise TemplatesNotFoundError from run() so a
library caller gets a catchable CfnLintExitException instead of a dead
process. The report has to come from a Runner that has loaded its rules:
JUnitFormatter returns None for an empty rule set and SARIFFormatter raises
KeyError, so reporting from main() would have emitted nothing for
--format junit and crashed for --format sarif.

Also export DuplicateRuleError, ConfigFileError and SchemaPatchError from
cfnlint.runner, which already exported the other two subclasses and is
where a library caller looks for them.
kddejong added a commit that referenced this pull request Oct 30, 2026
…4966)

Runner.__init__ reported an unresolvable --template glob by calling
_cli_output, which ends in sys.exit. Constructing a Runner therefore
terminated any process that embeds cfn-lint as a library, four lines above
the schema patching that #4911 fixed for the same reason. cfnlint.api
lint(), lint_file() and lint_by_config() all died the same way.

Record the error during construction and report it from cli() through the
unchanged _cli_output path, so the CLI keeps its exit code and byte-level
output for every --format, and raise TemplatesNotFoundError from run() so a
library caller gets a catchable CfnLintExitException instead of a dead
process. The report has to come from a Runner that has loaded its rules:
JUnitFormatter returns None for an empty rule set and SARIFFormatter raises
KeyError, so reporting from main() would have emitted nothing for
--format junit and crashed for --format sarif.

Also export DuplicateRuleError, ConfigFileError and SchemaPatchError from
cfnlint.runner, which already exported the other two subclasses and is
where a library caller looks for them.
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.

Schema patching calls sys.exit(1) from library code, writes the error to stdout, and swallows some override spec read errors

2 participants