Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/zizmor-fail-high-severity.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@ const esmRuleTester = new RuleTester({
describe("require-fetch-response-body-try-catch", () => {
it("valid: direct chain wrapped in try/catch passes (CommonJS)", () => {
cjsRuleTester.run("require-fetch-response-body-try-catch", requireFetchResponseBodyTryCatchRule, {
valid: [
`async function f() { try { const data = await fetch(url).json(); } catch (e) {} }`,
`async function f() { try { const data = await fetch(url).text(); } catch (e) {} }`,
],
valid: [`async function f() { try { const data = await fetch(url).json(); } catch (e) {} }`, `async function f() { try { const data = await fetch(url).text(); } catch (e) {} }`],
invalid: [],
});
});
Expand Down
10 changes: 4 additions & 6 deletions pkg/cli/compile_pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,9 @@ func compileSpecificFiles(
return workflowDataList, err
}
if err := RunZizmorOnFiles(lockFilesForZizmor, config.Verbose && !config.JSONOutput, config.Strict); err != nil {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is a no-op for the stated goal: RunZizmorOnFiles returning an error here still gets swallowed by handleBatchToolError (in pkg/cli/compile_external_tools.go) whenever strict is false, so high/critical zizmor findings will not fail compilation in non-strict mode despite this diff.

💡 Why this doesn't fix the bug

The call chain is:

RunZizmorOnFiles(...) -> runBatchLockFileTool(...) -> handleBatchToolError(toolName, err, strict, verbose)

and handleBatchToolError is:

func handleBatchToolError(toolName string, err error, strict, verbose bool) error {
	if err == nil {
		return nil
	}
	if strict {
		return fmt.Errorf("%s failed: %w", toolName, err)
	}
	// In non-strict mode, errors are warnings
	if verbose {
		fmt.Fprintln(os.Stderr, ...)
	}
	return nil
}

Regardless of why runZizmorOnFiles returned an error (including the new high/critical-severity error path), handleBatchToolError unconditionally returns nil when strict is false. Removing the if config.Strict { return ... } guard at the call site in compile_pipeline.go therefore has no effect: the error never reaches this call site to begin with when strict is false, because it was already discarded one layer down.

I verified this experimentally by adding a throwaway unit test that calls runBatchLockFileTool("zizmor", ..., strict=false, ...) with a runner returning a high-severity-style error — it returns nil, confirming the swallow happens before RunZizmorOnFiles returns to compile_pipeline.go.

Suggested fix: handleBatchToolError needs to distinguish "must always fail" errors (e.g. wrap them in a sentinel type or check severity) from ordinary warnings, or RunZizmorOnFiles/runZizmorOnFiles needs to bypass handleBatchToolError entirely for the high/critical path and return the raw error directly to the caller instead of going through the shared warning-swallowing helper.

This should also get a regression test asserting that a high-severity zizmor error surfaces as a real error when strict=false.

if config.Strict {
return workflowDataList, err
}
// Always fail on high/critical severity findings (zizmor returns errors for those
// regardless of strict mode). In strict mode, all findings are errors.
return workflowDataList, err
Comment on lines 204 to +207
Comment on lines +205 to +207

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[/diagnosing-bugs] No regression test guards this fix — the bug could silently reappear if the RunZizmorOnFiles error-propagation logic changes.

Add a unit or integration test that calls compileSpecificFiles with config.Strict = false and a high/critical zizmor finding, asserting a non-nil error.

@copilot please address this.

}
}

Expand Down Expand Up @@ -514,9 +514,7 @@ func compileAllFilesInDirectory(
return workflowDataList, err
}
if err := RunZizmorOnFiles(lockFilesForZizmor, config.Verbose && !config.JSONOutput, config.Strict); err != nil {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same broken pattern as the other call site: handleBatchToolError still swallows this error whenever strict is false, so compileAllFilesInDirectory also fails to fail on high/critical zizmor findings.

💡 Details

See the companion comment on line 204 for the full call-chain explanation (RunZizmorOnFiles -> runBatchLockFileTool -> handleBatchToolError, which unconditionally returns nil for any error when strict is false). Fixing only one of the two call sites would not have been sufficient either way — the actual defect is in the shared handleBatchToolError helper, not at these call sites.

if config.Strict {
return workflowDataList, err
}
return workflowDataList, err
}
}

Expand Down
Loading