Skip to content

fix(workflows): match gate reject option case-insensitively#3335

Open
Noor-ul-ain001 wants to merge 1 commit into
github:mainfrom
Noor-ul-ain001:fix/gate-reject-case-insensitive
Open

fix(workflows): match gate reject option case-insensitively#3335
Noor-ul-ain001 wants to merge 1 commit into
github:mainfrom
Noor-ul-ain001:fix/gate-reject-case-insensitive

Conversation

@Noor-ul-ain001

Copy link
Copy Markdown
Contributor

Summary

A gate step authored with capitalised options — e.g. options: [Approve, Reject] — passes validate() but never aborts on rejection. Picking Reject silently falls through to the approval path and runs downstream steps.

Root cause

validate() accepts a reject option case-insensitively:

reject_choices = {"reject", "abort"}
if not any(o.lower() in reject_choices for o in options):
    errors.append(...)

So Reject is a valid reject option and the workflow validates fine. But _prompt echoes the option's original casing, and execute() compared it case-sensitively:

if choice in ("reject", "abort"):   # "Reject" != "reject" → False

The two checks disagree: validation lets Reject through as a reject option, then the runtime treats the same Reject pick as approval. on_reject: abort is silently skipped and downstream steps run.

Fix

Lower-case choice before the reject comparison so the runtime agrees with the validation that admitted the option:

if choice.lower() in ("reject", "abort"):

Test

test_gate_reject_matches_case_insensitively drives a gate with options: [Approve, Reject], forces a TTY, stubs _prompt to return the capitalised "Reject", and asserts the run reaches RunStatus.ABORTED and the downstream step never executes. Fails before the fix, passes after.

All 26 test_workflows.py gate tests pass.

🤖 Generated with Claude Code

`validate` accepts a reject option case-insensitively
(`o.lower() in {"reject", "abort"}`), so a gate authored as
`options: [Approve, Reject]` passes validation. But `execute`
compared the echoed choice case-sensitively, so picking `Reject`
fell through to the approval path and silently ran downstream
steps instead of aborting.

Lower-case `choice` before the reject comparison so the runtime
agrees with the validation that let the option through.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Noor-ul-ain001 Noor-ul-ain001 requested a review from mnriem as a code owner July 4, 2026 16:41
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.

1 participant