Skip to content

gate: TestNoDirectProcoderFileIO failed once on CI and was not reproducible #283

Description

@piwi3910

On the 3.6.0 release PR (#282) the gate job went red with:

BLOCKING  go tests: 1 test(s) failing: TestNoDirectProcoderFileIO (test)
procoder gate: 856 clean, 0 unformatted, 0 unchecked, 20 out of scope, 172 hygiene finding(s) (1 blocking)

A re-run of the same job on the same commit passed. Filing it rather than letting a green re-roll close the question.

What was checked, and what it ruled out

Check Result
test (ubuntu-latest) on the same commit — runs go test ./internal/... passed, including this test
test on macOS and Windows, same commit passed
CI's exact gate command locally: git ls-files | procoder check --paths-from - 0 blocking, 170 hygiene
The guard alone, uncached (-count=1) passes, 0.10s
The guard as part of its whole package passes
git status over internal/ and cmd/ after a gate run clean — nothing written into the tree
Tests writing .go files all under a t.TempDir() root; none writes into the repo tree

So it passed on ubuntu in one job and failed on ubuntu in another, on the same commit, and is deterministic everywhere it can be run by hand.

Leading hypotheses, neither confirmed

  1. Misattributed test name. internal/testrun parses --- FAIL: lines out of go test output. If a package failed to build, or output interleaved under parallelism, the reported name may not be the test that actually failed — in which case this test is a bystander and something else was red.
  2. A file parsed mid-write. checkFile calls parser.ParseFile and t.Fatalfs on error. The goFiles walk tolerates a vanishing file, but the parse does not tolerate a partial one. Nothing found writes .go files into the tree, so this needs a writer nobody has identified.

Why it matters more than one red run

This guard is what stops .procoder/ file access leaking outside internal/store, and it is wired into the release gate. A guard that fails for a reason nobody can name is one people learn to re-run, and a re-run habit is how the next real failure gets waved through.

Suggested next step

Make procoder test keep the failing package's raw output when it reports a failing test name, so the next occurrence carries the assertion rather than just the name. That turns an unreproducible report into a diagnosable one, whichever hypothesis is right.

Seen on: 3.6.0 release PR #282, run 34395461728, ubuntu-latest.

Activity

  1. piwi3910 commented on Sep 23, 2026

    @piwi3910
    ContributorAuthor

    Closing now that #297 has merged. procoder test reads go test -json, so a test that prints --- FAIL: is no longer counted as failing, and a package that failed outside any test is named with go's reason. The guard skips only a file that vanished between the walk and the parse. Every failure reported by procoder test or the gate now carries a bounded excerpt of its own output. Neither cause can be proven for run 34395461728, but a recurrence will now show its own error text. If it happens again, open a new issue with that excerpt.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions