Skip to content

[Visual Test] Label preflight rejects duplicate label on run #30192579914, skipping Lavapipe screenshot capture #952

Description

@MichaelFisher1997

Workflow

https://github.com/OpenStaticFish/ZigCraft/actions/runs/30192579914

Failure output

The visual-test job fails at the Ensure visual-test label exists step (2026-07-26T07:18:58Z schedule run). Subsequent steps including Run menu screenshot capture are skipped because the workflow uses if: success() on them, so build-output.log is never produced. The screenshot / Vulkan / PPM path therefore never runs.

The "failure output" block referenced by .github/prompts/visual-test-diagnose.md does not exist in the workspace, which is the expected symptom of this preflight failure — the prompt's hypothesis (screenshot.ppm rejected by detectScreenshotFormat) is not what the run actually does. .github/workflows/visual-test.yml:81 invokes zig build run -Dscreenshot-path=screenshot.png -Dskip-present=true, and screenshot.zig:262-267 only rejects the format the prompt fabricates (.ppm).

Reference failure from the previous day's run (identical error, full stderr):

label with name "run-visual-test" already exists; use `--force` to update its color and description
##[error]Process completed with exit code 1.

The same message is emitted by the Ensure visual-test label exists step in run 30192579914 (logs not yet accessible because the job is still in its post-failure diagnosis phase, but the job summary shows that step as the only failure X while every later step is - / skipped).

Diagnosis

The visual-test workflow does not fail in the Vulkan / screenshot capture path. The Zig build and Lavapipe screenshot run never execute because the preflight gh label list / gh label create step exits non-zero, which causes every later step (including Run menu screenshot capture and Check build log exists) to be skipped. build-output.log therefore does not exist in the workspace because the run-with-log action never ran.

Root cause is in .github/workflows/visual-test.yml:55-68 (Ensure visual-test label exists):

if ! gh label list --json name --jq '.[].name' | grep -q '^visual-test$'; then
  gh label create "visual-test" \
    --description "Issues from automated visual regression tests" \
    --color "E06C75"
fi
if ! gh label list --json name --jq '.[].name' | grep -q '^run-visual-test$'; then
  gh label create "run-visual-test" \
    --description "Run deterministic visual regression workflow on a PR" \
    --color "E06C75"
fi

gh label list paginates with a default page size of 30 and --jq '.[].name' only emits the first page. Once the repo accumulates enough labels that run-visual-test falls off page 1, the grep -q '^run-visual-test$' returns 1 and the workflow tries to recreate it; gh label create then errors with label with name "run-visual-test" already exists; use --force to update its color and description. Either branch causes set -e to abort the step with exit code 1.

This is the same failure that has been hitting the visual-test workflow every day since at least 2026-07-12 — see #916, #931, #935, #942, #944, #945, #946, #947, #949, #950. Issue #950 was filed for the previous day's run (30148576016) and is still open.

The stale .github/prompts/visual-test-diagnose.md (lines 7, 8, 9, 21, 42, 43) keeps misdirecting the diagnosis agent at a non-existent PPM failure every time build-output.log is missing, which has led to at least two duplicate / misdiagnosed issues (#949, and the rejected comment on #950).

Origin of the failure

  • File: .github/workflows/visual-test.yml
  • Step: Ensure visual-test label exists (lines 55-68)
  • Function: gh label list --json name --jq '.[].name' — paginated, only the first 30 labels returned
  • Logic: if ! ... grep -q '^run-visual-test$'; then gh label create ...; fi — recreates an already-existing label once it falls off page 1

Suggested fix

Either fetch all pages when listing labels, or make gh label create failures non-fatal:

if ! gh label list --json name --jq '.[].name' --paginate | grep -q '^visual-test$'; then
  gh label create "visual-test" \
    --description "Issues from automated visual regression tests" \
    --color "E06C75" || true
fi
if ! gh label list --json name --jq '.[].name' --paginate | grep -q '^run-visual-test$'; then
  gh label create "run-visual-test" \
    --description "Run deterministic visual regression workflow on a PR" \
    --color "E06C75" || true
fi

Adding --paginate ensures run-visual-test is found on later pages, and || true on the create calls makes the step idempotent against transient gh label create failures (network/API errors, partial outages that have been seen in earlier runner logs with Failed to restore: Cache service responded with 400 / Our services aren't available right now). After the fix, the actual Lavapipe / headless-swapchain / PNG screenshot capture path (headless swapchain at modules/engine-graphics/src/vulkan_swapchain.zig:127-174, PNG writer at modules/engine-graphics/src/vulkan/screenshot.zig:279-349, frame counting at src/game/app.zig:528-593) can finally be exercised end-to-end and reported on its own merits.

.github/prompts/visual-test-diagnose.md should also be updated to reference -Dscreenshot-path=screenshot.png (and screenshot.png) instead of screenshot.ppm so future diagnosis agents don't fabricate PPM-rejection output.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghotfixquestionFurther information is requestedvisual-testIssues from automated visual regression tests

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions