Skip to content

fix(runner): don't drop iteration 0 in the auto-finalize fallback - #6

Open
Osamaali313 wants to merge 1 commit into
VILA-Lab:mainfrom
Osamaali313:fix-finalize-drops-iter-0
Open

fix(runner): don't drop iteration 0 in the auto-finalize fallback#6
Osamaali313 wants to merge 1 commit into
VILA-Lab:mainfrom
Osamaali313:fix-finalize-drops-iter-0

Conversation

@Osamaali313

Copy link
Copy Markdown

What

The auto-finalize fallback in CodexRunner._reader_iter (scripts/figcopy_runner/codex.py) and ClaudeRunner._reader_iter (scripts/figcopy_runner/claude.py) silently drops iteration 0:

disk_iters = sorted(
    _parse_iter_n_from_path(p.name) or -1
    for p in workdir.glob("img_iter*.png")
)
disk_iters = [n for n in disk_iters if n >= 0]

_parse_iter_n_from_path returns an int or None. The or -1 is meant to turn the None sentinel into -1 so the next line can drop it — but 0 is falsy, so img_iter0.png parses to 0, 0 or -1 evaluates to -1, and the n >= 0 filter discards it.

Why it matters

Iterations are 0-based (the loop policy says Iterate N = 0..{max_iters-1}), so img_iter0.png is the ordinary first artifact. This block exists to salvage a run when the CLI exits non-zero mid-loop (e.g. turn budget exhausted). With the bug:

  • a run whose only artifact is iteration 0 -> disk_iters == [] -> auto-finalize is skipped -> the run is reported failed and no figure.png is written;
  • when iteration 0 is the floor-passing iteration, _pick_finalize_iter never sees it and a different (possibly worse) iteration ships.

The other three callers of the same helper (codex.py:1113, codex.py:1455, claude.py:794) all correctly use is None — only these two finalize sites use or -1, so it's a self-inconsistency.

only img_iter0.png present:  buggy disk_iters=[]      fixed disk_iters=[0]
img_iter0 + img_iter2:       buggy disk_iters=[2]      fixed disk_iters=[0, 2]

Fix

Mirror the sibling sites — keep only successfully-parsed indices, treating None (not 0) as the skip sentinel:

disk_iters = sorted(
    n
    for p in workdir.glob("img_iter*.png")
    if (n := _parse_iter_n_from_path(p.name)) is not None
)

Applied to both runners. No behavior change for runs whose lowest iteration is >= 1.

The scan lives inline in the _reader_iter finalize/exit block (not a standalone function), so it isn't directly unit-testable without driving the full runner — happy to extract it into a small helper with a regression test if you'd prefer.

The auto-finalize block in CodexRunner/ClaudeRunner._reader_iter computed
`_parse_iter_n_from_path(p.name) or -1` and then filtered `n >= 0`. Since 0
is falsy, `img_iter0.png` parsed to 0, `0 or -1` became -1, and the next line
discarded it. Iterations are 0-based ("Iterate N = 0..max_iters-1"), so this
silently erased the ordinary first artifact: a run whose only iteration is 0
(a normal early exit, e.g. turn budget exhausted) was reported failed with no
figure.png, and when iter 0 was the floor-passing iteration it could never be
selected for finalize.

Mirror the sibling call sites (codex.py:1113 / claude.py:794), which already
treat only None as the "unparseable" sentinel. Behavior is unchanged for any
run whose lowest iteration is >= 1.
Copilot AI lite review requested due to automatic review settings August 4, 2026 21:06

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Ready to approve

The change is a targeted, correct fix for a confirmed falsy-0 bug and aligns behavior with existing sibling call sites without introducing API or control-flow risk.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Pull request overview

Fixes a correctness bug in the runners’ auto-finalize fallback logic where img_iter0.png could be accidentally excluded from consideration due to 0 being falsy in Python. This ensures iteration indices are treated as 0-based consistently when salvaging a run after an early non-zero CLI exit.

Changes:

  • Update CodexRunner auto-finalize disk scan to keep parsed iteration indices (including 0) and skip only None.
  • Update ClaudeRunner auto-finalize disk scan with the same is not None parsing guard for consistency.
  • Remove the or -1 / >= 0 sentinel pattern that incorrectly dropped iteration 0.
File summaries
File Description
scripts/figcopy_runner/codex.py Fixes the finalize fallback’s on-disk iteration scan so img_iter0.png is not dropped.
scripts/figcopy_runner/claude.py Applies the same iteration-0-safe parsing pattern to Claude’s finalize fallback.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 0
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

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.

2 participants