fix(workflows): reject bool max_iterations in engine re-eval guard#3470
fix(workflows): reject bool max_iterations in engine re-eval guard#3470Noor-ul-ain001 wants to merge 2 commits into
Conversation
The While/DoWhile step validators already reject `max_iterations: true` as a type error (bool is an int subclass, so it would otherwise pass the `isinstance(..., int)` check and, since `True - 1 == 0`, silently cap the loop at a single iteration). The engine's re-evaluation guard used the older `not isinstance(max_iters, int) or max_iters < 1` shape, so on an unvalidated run a boolean slipped through and ran the loop body just once instead of falling back to the safe default of 10. Add the explicit `isinstance(max_iters, bool)` rejection so the engine guard matches the step validators and an unvalidated run degrades to the default rather than silently under-running the loop. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Fixes an engine-level edge case where max_iterations: true (a YAML boolean) could slip through an isinstance(..., int) guard and silently cap while/do-while loops to a single iteration when running an unvalidated workflow definition.
Changes:
- Updated the workflow engine loop re-evaluation guard to explicitly reject
boolvalues formax_iterations, falling back to the safe default (10). - Added a regression test that executes a
whileworkflow withmax_iterations: truethrough the engine and asserts the loop runs 10 times.
Show a summary per file
| File | Description |
|---|---|
tests/test_workflows.py |
Adds a regression test ensuring max_iterations: true falls back to the default iteration cap when executed via the engine. |
src/specify_cli/workflows/engine.py |
Updates the engine’s loop guard to treat booleans as invalid for max_iterations and default to 10. |
Review details
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 2/2 changed files
- Comments generated: 0
- Review effort level: Low
…ations-bool-guard # Conflicts: # src/specify_cli/workflows/engine.py # tests/test_workflows.py
|
Conflicts resolved — merged the latest While resolving I found the conflict was substantive, not just textual: if (
isinstance(max_iters, bool)
or not isinstance(max_iters, int)
or max_iters < 1
):
max_iters = 10— and an equivalent engine-level regression test ( I resolved both conflicts by taking Since the fix is already upstream, this PR no longer adds anything and is a reasonable candidate to close as superseded — happy to do that, or leave it open if you would prefer. Just flagging so the empty diff is not a surprise. |
|
Closing as superseded as indicated by the comment above |
Summary
The
while/do-whilestep validators already rejectmax_iterations: trueas a type error —boolis a subclass ofint, so a boolean passes a bareisinstance(..., int)check, and sinceTrue - 1 == 0it would silently cap the loop at a single iteration (0 re-iterations).The engine's re-evaluation guard in
WorkflowEngine, however, still used the older shape:On an unvalidated run (executing a definition without first calling the validators), a boolean
max_iterationsslipped through this guard and ran the loop body just once instead of falling back to the safe default of 10.Fix
Add the explicit
isinstance(max_iters, bool)rejection so the engine guard matchesWhileStep.validate()/DoWhileStep.validate(). An unvalidated run now degrades to the default of 10 rather than silently under-running the loop.Testing
test_while_loop_bool_max_iterations_falls_back_to_default, which runs awhilestep withmax_iterations: truethrough the engine and asserts the body executes 10 times (not 1).git stash).🤖 Generated with Claude Code