[high] Exit non-zero and keep converting when a rule fails with --output-dir - #98
Merged
thomaspatzke merged 3 commits intoSep 27, 2026
Merged
Conversation
write_separate_files() wrapped the whole backend.convert() call in 'except Exception' and only printed a warning, so a single unconvertible rule dropped every rule after it and the command still exited 0. Rules are now converted one by one (like Backend.convert does), failures are reported per rule, the remaining rules are still written and the command exits with status 1. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
thomaspatzke
approved these changes
Sep 27, 2026
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The new tests assert stderr-emitted messages via result.output, which can be incorrect under Click’s separated stdout/stderr capture, risking flaky or failing tests.
Review effort: Lite
Findings: 1
Open (2)
What changed in this PR
This PR fixes sigma convert --output-dir so conversion errors are no longer silently downgraded to warnings with exit code 0, and so later rules still get converted/written even if an earlier rule fails—making the command safer for CI usage.
Changes:
- Convert rules one-by-one in
write_separate_files()to continue after per-rule conversion failures. - Exit non-zero when any rule fails to convert (while still writing outputs for successful rules).
- Add CLI tests covering “fail + continue” behavior and
--skip-unsupportedbehavior with--output-dir.
| File | Description |
|---|---|
sigma/cli/convert.py |
Switches --output-dir conversion to per-rule processing and raises an error if any rule fails. |
tests/test_convert.py |
Adds regression tests for non-zero exit on conversion failure while still writing later rules, plus --skip-unsupported guard. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Update assertions to check stderr instead of output. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
thomaspatzke
approved these changes
Sep 27, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


BLUF
--output-dir, any conversion error is downgraded to a warning and the command exits 0. Every rule after the failing one is silently dropped.sigma convert -t <backend> -od out/ rules/in a CI job reports success whileout/is incomplete, and can even be empty. The same input without-odexits 1.write_separate_files(), report each failing rule, keep writing the others, and exit 1 when any rule failed.mainand passes with the fix. The second guards--skip-unsupported(still exit 0, reported under "Ignored errors").Priority: high
Details
Root cause:
sigma/cli/convert.py:192-195Backend.convert()is a single list comprehension over all rules. The first exception aborts it, so the callback never runs for later rules. The exception is then swallowed. The single-output path (convert.py:590-601) turns the sameSigmaError/NotImplementedErrorintoError while converting: ...with exit status 1.The fix does what
Backend.convert()does:init_processing_pipeline()andresolve_rule_references(), thenconvert_rule()/convert_correlation_rule()in collection order with the existing callback. The difference is thatSigmaError/NotImplementedErroris caught per rule.finalize()is not called, but the old code discarded its return value anyway. After the files are written, aClickExceptionreports the number of failed rules.-s/--skip-unsupportedstill works as before. In that mode the backend collectsSigmaErrors itself (collect_errors=True), and they are listed under "Ignored errors" with exit 0.Before (rule
a.ymluses an unresolvable|expandplaceholder,b.ymlis fine):After:
This PR is independent of the other
--output-dirPR, which changes the write loop of the same function. Whichever lands second, I'll rebase it.Testing
test_convert_output_dir_conversion_error_fails_and_continues(fails onmain, passes here) andtest_convert_output_dir_conversion_error_skip_unsupported.poetry.lock: pySigma 1.4.0, click 8.4.2, pyparsing 3.3.2):pytest --cov=sigma→ 120 passed, 1 skipped.🤖 Generated with Claude Code