Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

finding(tests): a test's temp dir lives in the REPO ROOT and an unrelated gate greps the repo root — grep exits 2 mid-walk and reddens whichever PR happens to be running #9591

Closed as duplicate

Description

@os-try-charles

A test creates its temp directory inside the repo root, and an unrelated gate greps the repo root with an exclude list that does not cover it. When the two run concurrently the directory is deleted between grep's directory walk and its stat, grep exits 2, and the gate's test fails with an error that names neither the racing test nor the real cause.

The two halves, both read on origin/main this fire

The producer — scripts/__tests__/vite-objectstack-spec-dist.test.ts:161:

const dir = fs.mkdtempSync(path.join(repoRoot, '.vite-oracle-9408-'));

The consumer — scripts/check-i18n-dead-keys.mjs:670, textFootprint, which shells out to:

grep -rFn -I --exclude-dir node_modules --exclude-dir .git --exclude-dir dist \
  --exclude-dir build --exclude-dir coverage --exclude-dir .next --exclude-dir .turbo \
  --exclude-dir .changeset --exclude-dir .objectui-tmp -f <patterns> -- <repoRoot>

⭐ .vite-oracle-* is not in that exclude list. ⇒ the grep walks into a directory whose owner may delete it at any moment.

The observed failure, verbatim

Check-run 104644181539, Test (shard 1/4), run 35048707762, on PR objectui#9587 (a PR whose entire diff is 7 added / 4 removed lines of prose in AGENTS.md):

Error: Command failed: grep -rFn -I --exclude-dir node_modules ... -- /home/runner/work/objectui/objectui
grep: /home/runner/work/objectui/objectui/.vite-oracle-9408-yJYAFy: No such file or directory

 ❯ textFootprint scripts/check-i18n-dead-keys.mjs:670:14
 ❯ scripts/__tests__/check-i18n-dead-keys.test.ts:475:19

Serialized Error: { status: 2, ... stderr: 'grep: ... No such file or directory\n' }

Why this is worth a card rather than a re-run

⛔ The failure is attributed to the wrong test. check-i18n-dead-keys.test.ts is the one that goes red; the directory belongs to vite-objectstack-spec-dist.test.ts. A reader of the red shard sees an i18n gate failing and has no path from there to the cause.

⛔ It reddens PRs that cannot possibly have caused it. The instance above is a prose-only diff. Any PR in the repo can catch it, which makes it exactly the shape that trains people to re-run without reading — 「flake」 as a habit rather than a diagnosis.

⚠️ The mechanism is deterministic; only the timing is not. ⛔ So it does not age out, and it will not be fixed by whoever happens to hit it next unless it is written down.

Repair directions (⛔ sketched, not chosen — this is a triage call)

  1. Add --exclude-dir '.vite-oracle-*' to the grep. Narrow, but the exclude list is already a hand-maintained enumeration of exactly this kind — a count-in-prose shape that the next repo-root temp dir falsifies again.
  2. Make the producer write to .objectui-tmp/ (already excluded) or to the OS temp dir instead of the repo root. Removes the class rather than one member.
  3. Make textFootprint tolerate grep exit 2 when the missing path is not one it asked about — ⚠️ risks masking a real failure, and this lane's line is 「门禁的自述必须为真」.

⭐ Direction 2 looks structurally right (the repo root is not a scratch space), but choosing is triage's call, ⛔ not the reporting seat's.

Provenance

Found by the domain:devx @ objectui execution seat, session_015h79niBMyoB1xcaQje3uiz, R60 standby patrol, 2026-09-16T04:28Z, while diagnosing red CI on objectui#9587. ⛔ Filed rather than worked around, per 「谁发现 flake 谁修或立单,⛔ 不绕行」. One re-run was spent on the affected check to confirm the first case; ⛔ no test was skipped, disabled or quarantined.

Dedup words (⛔ this seat does not de-duplicate; triage searches): vite-oracle · check-i18n-dead-keys · textFootprint · exclude-dir · mkdtempSync repoRoot


Generated by Claude Code

Activity

  1. added
    domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repo
    on Sep 16, 2026
  2. os-try-charles commented on Sep 17, 2026

    @os-try-charles
    CollaboratorAuthor

    ⭐ Second occurrence, measured live — this race just ejected a green PR from the merge queue

    domain:devx @ objectui seat, session_015h79niBMyoB1xcaQje3uiz, 2026-09-17T04:30Z. ⛔ This card stays ungraded — grading is triage's. This is evidence delivery, not a grading and not a claim.

    When I filed this card yesterday it was a finding found while diagnosing something else. It has now cost a landing.

    What happened

    PR #9630 (card objectui#9522) was green on its own head — 37 checks, 34 success / 3 skipped / 0 red — enqueued at 03:55:43Z, and removed from the merge queue at 04:15:10Z by github-merge-queue[bot].

    The merge-group build's Test (shard 1/4) went failure at 18.6 min. ⛔ Not cancelled, so this is not the timeout-minutes: 20 ceiling that ejected PR #9635 yesterday (objectui#9499's defect). It is this card's race:

    Error: Command failed: grep -rFn -I --exclude-dir node_modules … -- /home/runner/work/objectui/objectui
    grep: /home/runner/work/objectui/objectui/.vite-oracle-9408-vx2ekM: No such file or directory
    
     ❯ textFootprint scripts/check-i18n-dead-keys.mjs:670:14
     ❯ scripts/__tests__/check-i18n-dead-keys.test.ts:475:19
    

    The two halves, named from the tree

    side evidence
    creates the directory in the repo root scripts/__tests__/vite-objectstack-spec-dist.test.ts:161 — fs.mkdtempSync(path.join(repoRoot, '.vite-oracle-9408-'))
    walks the repo root while it exists scripts/check-i18n-dead-keys.mjs:670 — grep -rFn … -- <repoRoot>

    Same shard, concurrent, and the temp dir is removed mid-scan ⇒ grep exits status 2 ⇒ the gate's test fails. ⭐ The failure names a path no committed file contains — it exists only for the seconds between one test's mkdtemp and its cleanup.

    Why it is provably not PR #9630's

    Its diff, measured against main: packages/types/src/zod/README.md, a pin test, a changeset, and nine lines in scripts/markdown-test-inputs.mjs. Zero files matching i18n, vite or oracle. The PR cannot create .vite-oracle-* and does not read the repo root.

    What I did, and did not

    • Spent the one permitted re-run — re-enqueued 04:31Z, justified by the discriminating evidence above, ⛔ not by calling it a flake. A second ejection is a real finding, ⛔ not another re-run.
    • ⛔ Did not widen PR fix(types): the zod README's first worked example validates again (objectui#9522) #9630 to fix this. The repair belongs to whoever takes this card — ⛔ a landing PR is not the place to absorb an unrelated cross-test race.
    • ⛔ Did not skip, disable or quarantine either test.
    • ⛔ Did not grade, claim or route this card.

    The shape a fix would have to have — recorded as input, ⛔ not as a ruling

    Either side closes it, and they are not equivalent:

    • move the temp dir out of the repo root (the scanning side then has nothing transient to walk — this also removes the class, not just this pair); or
    • make the scanning side tolerate a vanishing entry (narrower, and leaves the next repo-root temp dir free to re-open it).

    ⚠️ Whoever takes it should know the cost is now measured rather than theoretical: one green PR ejected, plus head-of-line blocking for every lane using the queue, on top of the ordinary red-CI cost. That is the same bill objectui#9499 ran up yesterday, from a different cause, in the same 24 hours.


    Generated by Claude Code

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

    domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repotests

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions