voidzero-dev / voidzero-dev/vite-task

Negative `input` pattern is ignored for files discovered via `readdir`

Open
#504 2 comments 0 reactions 1 assignee View on GitHub

@wan9chi is already working on this.

Since Jul 3, 2026.

Dominant language
Rust
Stars
466
Forks
42
Avg merge
1d 15h
Merged PRs (30d)
19

Description

Summary

A negative input pattern ("!path") correctly excludes a file a task reads by direct path, but does not exclude a file the task discovers through a directory listing (readdir). When such a file is a build artifact that is absent on a fresh checkout, its removal invalidates the cache with Removed, so the cache never hits, even though a negative pattern for that exact path is present.

Reproduction

https://github.com/why-reproductions-are-required/vite-task-negative-input-pattern-readdir

pnpm install
./repro.sh

The repro defines two tasks that differ only in how they discover an excluded, generated artifact:

// BUG: artifact found via readdir("assets")
"readdir-case": {
  command: "node -e \"fs.readdirSync('assets'); fs.writeFileSync('assets/generated.txt', ...)\"",
  input: [{ auto: true }, "!assets/generated.txt"],
},
// CONTROL: artifact read by direct path
"direct-path-case": {
  command: "node -e \"try { fs.readFileSync('direct.txt') } catch {}; fs.writeFileSync('direct.txt', ...)\"",
  input: [{ auto: true }, "!direct.txt"],
},

Expected vs actual

Each task is run 3 times; run 3 removes the excluded artifact before running. Removing an excluded file should keep the cache valid.

task discovery run 3 result
direct-path-case readFileSync HIT (correct)
readdir-case readdirSync MISS: InputChanged { Removed, "assets/generated.txt" }

Only the discovery method differs.

Impact

Real builds routinely list a directory that also contains generated files. In a Vite + void app the build lists directories holding .void/queues.d.ts, .void/routes.d.ts, public/feed.xml, public/sitemap.xml, public/posts/, etc. On a fresh CI checkout those files do not exist yet, so the cache misses on every run even with a negative pattern for each of them. The only workaround I found is to abandon { auto: true } and enumerate every input explicitly.

Possibly related

crates/vite_task/src/session/execute/fingerprint.rs notes that negative-glob filtering for the post-run fspy fingerprint is "done upstream" and that paths already in globbed_inputs are skipped; PathRead { read_dir_entries: bool } distinguishes directory-listing reads. The negative filter appears not to reach entries surfaced by a directory listing.

Environment

  • vite-plus 0.2.2 (bundles Vite Task)
  • Reproduced on macOS (darwin 25.x) and GitHub Actions ubuntu-latest

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.