Skip to content

Update dependency vitest to v4 [SECURITY] - #798

Open
renovate[bot] wants to merge 3 commits into
masterfrom
renovate/npm-vitest-vulnerability
Open

renovate[bot] wants to merge 3 commits into
masterfrom
renovate/npm-vitest-vulnerability

Conversation

@renovate

@renovate renovate Bot commented Sep 9, 2026 •

Copy link
Copy Markdown
Contributor

ℹ️ Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Change Age Confidence
vitest (source) ^3.2.6 → ^4.0.0 age confidence

Vitest: Path Traversal / Arbitrary File Read via @​vitest/mocker Redirect Mock

CVE-2026-84373 / GHSA-82fw-gwwq-j7x9

More information

Details

Summary

@vitest/mocker registers a redirect mock's target path without validating it
against the dev server's file-serving allowlist. An attacker who can reach the
dev server's WebSocket can register a redirect mock pointing outside the project
root; when the mocked module is requested, the plugin's load hook returns
readFile(<attacker path>) as the module source, disclosing local files.

This is exploitable without authentication only through the public
mockerPlugin / standalone interceptorPlugin exports (used by third-party dev
servers), which register the handler on Vite's unauthenticated HMR socket.
Vitest's own browser mode registers mocks over a token-authenticated RPC and
is not remotely reachable by default (see Scope).

Affected code

packages/mocker/src/node/interceptorPlugin.ts.

The load hook is the file-read sink:

if (mock.type === 'redirect') {
  return readFile(mock.redirect, 'utf-8')
}

mock.redirect is derived from client input at registration time with no
boundary check:

if (event.type === 'redirect') {
  const redirectUrl = new URL(event.redirect)
  event.redirect = join(server.config.root, redirectUrl.pathname)
}
registry.register(event)

There is no server.fs.allow / server.fs.deny check and no assertion that the
resolved path stays within the project root.

Registration paths and trust boundaries
  • Public mockerPlugin / interceptorPlugin (unauthenticated). In
    configureServer, the plugin registers server.ws.on('vitest:interceptor:register', …)
    on Vite's HMR WebSocket. That socket performs no token, Origin, or same-origin
    check, so any client that can reach it can register a redirect mock. This is
    the path the "unauthenticated" impact applies to.
  • Vitest browser mode (authenticated). Mocks register over the browser RPC
    (registerMock), which sits behind a per-run token (isValidApiRequest, a
    random api.token). The interceptor's configureServer socket is not used for
    registration here (in v5 it does not run at all, as the plugin is injected per
    environment). The same missing boundary check exists on the authenticated RPC
    path, but reaching it requires the token, so it is not a remote-unauthenticated
    read.
Path handling

new URL(redirect).pathname combined with join(root, pathname) does not
confine reads to the root:

  • Special/hierarchical schemes (file:, http:) are normalized by WHATWG URL,
    so .. segments are collapsed and the result stays under the root. Payloads of
    the form file:///../../etc/passwd do not escape.
  • A non-special (opaque) scheme preserves .. in pathname, so
    join(root, "../../…/etc/passwd") resolves outside the root and reads an
    arbitrary file.

Even without escaping the root, the missing server.fs check allows reading any
in-root file the dev server would otherwise refuse to serve (for example an
in-root .env or source that is denied by server.fs.deny).

Scope / preconditions
  • This is a development-server issue. The dev server binds to localhost by
    default and is not reachable from the network unless the developer exposes it
    (server.host / 0.0.0.0, a LAN bind, or a proxy).
  • A raw (non-browser) client against a reachable server bypasses browser origin
    and CORS protections entirely and can both register the mock and read the
    response.
  • A browser-based drive-by against a localhost server is substantially mitigated
    by Vite defaults: the default CORS origin allowlist is limited to localhost
    origins, and server.allowedHosts blocks DNS-rebinding, so a cross-origin page
    cannot read the file contents back.
Impact

Disclosure of local files readable by the dev-server process (source, in-root
.env/secrets, and, via the opaque-scheme payload, files outside the project
root). No integrity or availability impact.

Affected versions

Present since @vitest/mocker was introduced.

  • Affected: @vitest/mocker >= 2.1.0 (shipped in vitest and
    @vitest/browser >= 2.1.0), through 4.1.x and the 5.0.0 pre-releases.
  • Fixed: Vitest 4.1.11 and 5.0.0. Older majors (2.1.x, 3.x) are not
    maintained and are not planned to receive the fix.
Fix

Validate the resolved redirect target against Vite's file-serving allowlist
(isFileLoadingAllowed) before registering it, at every registration site, and
stop registering the interceptor WebSocket events in Vitest's browser mode
(mocks there flow through the authenticated RPC).

Severity

  • CVSS Score: 5.9 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Vitest: Path Traversal / Arbitrary File Read via @​vitest/mocker Redirect Mock

CVE-2026-84373 / GHSA-82fw-gwwq-j7x9

More information

Details

Summary

@vitest/mocker registers a redirect mock's target path without validating it
against the dev server's file-serving allowlist. An attacker who can reach the
dev server's WebSocket can register a redirect mock pointing outside the project
root; when the mocked module is requested, the plugin's load hook returns
readFile(<attacker path>) as the module source, disclosing local files.

This is exploitable without authentication only through the public
mockerPlugin / standalone interceptorPlugin exports (used by third-party dev
servers), which register the handler on Vite's unauthenticated HMR socket.
Vitest's own browser mode registers mocks over a token-authenticated RPC and
is not remotely reachable by default (see Scope).

Affected code

packages/mocker/src/node/interceptorPlugin.ts.

The load hook is the file-read sink:

if (mock.type === 'redirect') {
  return readFile(mock.redirect, 'utf-8')
}

mock.redirect is derived from client input at registration time with no
boundary check:

if (event.type === 'redirect') {
  const redirectUrl = new URL(event.redirect)
  event.redirect = join(server.config.root, redirectUrl.pathname)
}
registry.register(event)

There is no server.fs.allow / server.fs.deny check and no assertion that the
resolved path stays within the project root.

Registration paths and trust boundaries
  • Public mockerPlugin / interceptorPlugin (unauthenticated). In
    configureServer, the plugin registers server.ws.on('vitest:interceptor:register', …)
    on Vite's HMR WebSocket. That socket performs no token, Origin, or same-origin
    check, so any client that can reach it can register a redirect mock. This is
    the path the "unauthenticated" impact applies to.
  • Vitest browser mode (authenticated). Mocks register over the browser RPC
    (registerMock), which sits behind a per-run token (isValidApiRequest, a
    random api.token). The interceptor's configureServer socket is not used for
    registration here (in v5 it does not run at all, as the plugin is injected per
    environment). The same missing boundary check exists on the authenticated RPC
    path, but reaching it requires the token, so it is not a remote-unauthenticated
    read.
Path handling

new URL(redirect).pathname combined with join(root, pathname) does not
confine reads to the root:

  • Special/hierarchical schemes (file:, http:) are normalized by WHATWG URL,
    so .. segments are collapsed and the result stays under the root. Payloads of
    the form file:///../../etc/passwd do not escape.
  • A non-special (opaque) scheme preserves .. in pathname, so
    join(root, "../../…/etc/passwd") resolves outside the root and reads an
    arbitrary file.

Even without escaping the root, the missing server.fs check allows reading any
in-root file the dev server would otherwise refuse to serve (for example an
in-root .env or source that is denied by server.fs.deny).

Scope / preconditions
  • This is a development-server issue. The dev server binds to localhost by
    default and is not reachable from the network unless the developer exposes it
    (server.host / 0.0.0.0, a LAN bind, or a proxy).
  • A raw (non-browser) client against a reachable server bypasses browser origin
    and CORS protections entirely and can both register the mock and read the
    response.
  • A browser-based drive-by against a localhost server is substantially mitigated
    by Vite defaults: the default CORS origin allowlist is limited to localhost
    origins, and server.allowedHosts blocks DNS-rebinding, so a cross-origin page
    cannot read the file contents back.
Impact

Disclosure of local files readable by the dev-server process (source, in-root
.env/secrets, and, via the opaque-scheme payload, files outside the project
root). No integrity or availability impact.

Affected versions

Present since @vitest/mocker was introduced.

  • Affected: @vitest/mocker >= 2.1.0 (shipped in vitest and
    @vitest/browser >= 2.1.0), through 4.1.x and the 5.0.0 pre-releases.
  • Fixed: Vitest 4.1.11 and 5.0.0. Older majors (2.1.x, 3.x) are not
    maintained and are not planned to receive the fix.
Fix

Validate the resolved redirect target against Vite's file-serving allowlist
(isFileLoadingAllowed) before registering it, at every registration site, and
stop registering the interceptor WebSocket events in Vitest's browser mode
(mocks there flow through the authenticated RPC).

Severity

  • CVSS Score: 5.9 / 10 (Medium)
  • Vector String: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N

References

This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).


Release Notes

vitest-dev/vitest (vitest)

v4.1.11

Compare Source

   🐞 Bug Fixes
    View changes on GitHub

v4.1.10

Compare Source

   🐞 Bug Fixes
    View changes on GitHub

v4.1.9

Compare Source

🐞 Bug Fixes
  • Fix importOriginal with optimizer and query import [backport to v4] - by Hiroshi Ogawa, David Harris, Codexand Vladimir in #​10546 (a5180)
  • browser:
    • Wait for orchestrator readiness before resolving browser sessions [backport to v4] - by Vladimir and Séamus O'Connor in #​10555 (7fb29)
    • Wait for iframe tester readiness before preparing [backport to v4] - by Vladimir and Séamus O'Connor in #​10497 and #​10556 (fbc62)
  • mocker:
    • Hoist vi.mock() for vite-plus/test imports [backport to v4] - by Hiroshi Ogawa, LongYinan, Claude Opus 4.8 and Vladimir in #​10548 (2c955)
  • pool:
    • Prevent test run hang on worker crash [backport to v4] - by Ari Perkkiö and Jattioui Ismail in #​10543 and #​10564 (934b0)
View changes on GitHub

v4.1.8

Compare Source

   🐞 Bug Fixes
    View changes on GitHub

v4.1.7

Compare Source

   🐞 Bug Fixes
    View changes on GitHub

v4.1.6

Compare Source

   🐞 Bug Fixes
   🏎 Performance
    View changes on GitHub

v4.1.5

Compare Source

   🚀 Experimental Features
   🐞 Bug Fixes
    View changes on GitHub

v4.1.4

Compare Source

   🚀 Features
   🐞 Bug Fixes
    View changes on GitHub

v4.1.3

Compare Source

   🚀 Experimental Features
   🐞 Bug Fixes
    View changes on GitHub

v4.1.2

Compare Source

This release bumps Vitest's flatted version and removes version pinning to resolve flatted's CVE related issues (#​9975).

   🐞 Bug Fixes
    View changes on GitHub

v4.1.1

Compare Source

   🚀 Features
   🐞 Bug Fixes
    View changes on GitHub

v4.1.0

Compare Source

Vitest 4.1 is out!

This release page lists all changes made to the project during the 4.1 beta. To get a review of all the new features, read our blog post.

   🚀 Features

❗ Important

✂ PR body was truncated to here.


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about these updates again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.


PR-Codex overview

This PR focuses on updating the vitest dependency across multiple packages and enhancing coverage configuration in various vitest.config.ts files.

Detailed summary

  • Updated vitest from ^3.2.6 to ^4.0.0 in several package.json files.
  • Updated @vitest/coverage-v8 from ^3.2.6 to ^4.0.0.
  • Enhanced coverage configuration in vitest.config.ts files to include TypeScript files and update reporters.
  • Added include and exclude patterns for coverage in multiple vitest.config.ts files.

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

@renovate
renovate Bot requested a review from a team as a code owner September 9, 2026 04:04
@changeset-bot

changeset-bot Bot commented Sep 9, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 3ed763c

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 216bb7dd46

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

"dotenv": "^8.2.0",
"size-limit": "^11.2.0",
"vitest": "^3.2.6"
"vitest": "^4.0.0"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Upgrade the matching Vitest coverage provider

When general_vi_test runs these workspaces with test --coverage (.github/workflows/ci.yml:232-241), each still installs @vitest/coverage-v8 3.2.6 while Vitest now resolves to 4.1.11. The lockfile shows that the provider requires exactly Vitest 3.2.6 (yarn.lock:6783-6802) and Vitest 4.1.11 requests provider 4.1.11 (yarn.lock:16120); Yarn consequently reports incompatible peer dependencies, and coverage execution loads an incompatible provider. Upgrade @vitest/coverage-v8 alongside Vitest in actions, core, and viem-account-ledger.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Addressed in 32fc91c: @vitest/coverage-v8 moved to ^4.0.0 in actions, core and viem-account-ledger; yarn why shows a single 4.1.11 resolution next to vitest 4.1.11, and the fetchCache crash is gone. Leaving the thread for a human to resolve.

@github-actions

github-actions Bot commented Sep 9, 2026 •

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size
require('@celo/actions') (cjs) 98.85 KB (0%)
import * from '@celo/actions' (esm) 23.55 KB (0%)
import { resolveAddress } from '@celo/actions' (esm) 23.49 KB (0%)
import { getGasPriceOnCelo } from '@celo/actions' (esm) 73 B (0%)
import { getAccountsContract } from '@celo/actions/contracts/accounts' (esm) 46.11 KB (0%)
import * from '@celo/actions/staking' (esm) 50.66 KB (0%)

@codecov

codecov Bot commented Sep 9, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 67.05%. Comparing base (b48cea3) to head (3ed763c).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #798      +/-   ##
==========================================
- Coverage   70.73%   67.05%   -3.69%     
==========================================
  Files         161      148      -13     
  Lines        8168     9501    +1333     
  Branches     1574     1842     +268     
==========================================
+ Hits         5778     6371     +593     
- Misses       2303     3051     +748     
+ Partials       87       79       -8     
Components Coverage Δ
celocli 59.73% <ø> (-10.84%) ⬇️
sdk 67.34% <ø> (-2.21%) ⬇️
wallets 73.68% <ø> (ø)
viem-sdks ∅ <ø> (∅)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@renovate
renovate Bot force-pushed the renovate/npm-vitest-vulnerability branch from 216bb7d to 13409a5 Compare September 9, 2026 13:56
@renovate
renovate Bot force-pushed the renovate/npm-vitest-vulnerability branch from 13409a5 to 03501d6 Compare September 30, 2026 23:16
renovate Bot and others added 2 commits October 7, 2026 10:25
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
The coverage provider must match the vitest major. With vitest 4.1.11
and @vitest/coverage-v8 3.2.6 installed side by side, every vitest
workspace run with --coverage aborted at report time with
"TypeError: Cannot read properties of undefined (reading 'fetchCache')"
and yarn reported unmet peer requirements in both directions. Moving
the provider to the same ^4.0.0 range resolves both to 4.1.11.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@pahor167
pahor167 force-pushed the renovate/npm-vitest-vulnerability branch from 03501d6 to 32fc91c Compare October 7, 2026 08:29
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-08T04:25:04.728610Z 3ed763c New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 32fc91cf65

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

"dotenv": "^8.2.0",
"size-limit": "^11.2.0",
"vitest": "^3.2.6"
"vitest": "^4.0.0"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restore all-source coverage after upgrading Vitest

When .github/workflows/ci.yml runs the actions, core, and viem-account-ledger workspaces with --coverage, Vitest 4 reports only files loaded during the test run when coverage.include is undefined because coverage.all and its all-files default were removed, as documented in the Vitest 4 migration guide. All three workspace configs specify only coverage.exclude, so unimported source files—for example, several contract modules in actions—now disappear from LCOV rather than appearing with zero coverage, inflating Codecov results and potentially allowing untested additions to bypass the patch-coverage check. Add an explicit source glob such as coverage.include: ['src/**/*.ts'] to each affected config as part of this upgrade.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Addressed in 3ed763c: coverage.include: ["src/**/*.ts"] added to all three vitest configs. Verified locally that the LCOV file set equals the non-test src/**/*.ts set minus the existing data/tokens/test-utils excludes (21 files in actions, 5 in core, 7 in viem-account-ledger), matching what Vitest 3 reported. Leaving the thread for a human to resolve.

@renovate

renovate Bot commented Oct 7, 2026

Copy link
Copy Markdown
Contributor Author

Edited/Blocked Notification

Renovate will not automatically rebase this PR, because it does not recognize the last commit author and assumes somebody else may have edited the PR.

You can manually request rebase by checking the rebase/retry box above.

⚠️ Warning: custom changes will be lost.

@pahor167

pahor167 commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Dependency sweep status for this PR (head 32fc91c, rebased on current master):

What fails: General vitest — 7 tests in packages/viem-account-ledger/src/ledger-to-account.test.ts, all in the respects the AddressValidation enum block (never, initializationOnly, firstTransactionPerAddress, everyTransaction, for both the celo and ethereum apps). Every assertion is off by exactly one: expected 2 to be 1, expected 3 to be 2, expected 4 to be 3 (job: https://github.com/celo-org/developer-tooling/actions/runs/37594164481/job/112705924128). The earlier TypeError: Cannot read properties of undefined (reading 'fetchCache') crash is gone: it came from @vitest/coverage-v8 3.2.6 being loaded next to vitest 4.1.11, and 32fc91c moves the provider to the same ^4.0.0 range (resolves to 4.1.11), which also addresses the Codex P1 above. @celo/core and @celo/actions pass with coverage on this head.

Root cause: Vitest 4 changed vi.spyOn so that spying on an already-spied method returns the existing spy instead of wrapping the original again (migration guide: "Calling vi.spyOn on a mock now returns the same mock"). The block's beforeEach calls ledgerToAccount(...) before spy = vi.spyOn(TestLedger.prototype, 'getAddress'), and afterEach only does spy.mockClear(). Under Vitest 3 each vi.spyOn created a fresh spy, so that beforeEach call was never counted. Under Vitest 4 the spy from the previous test is still installed, records the beforeEach init call, and vi.spyOn hands that same spy back, so every count is one too high.

Fix that would make it green: in ledger-to-account.test.ts, change the afterEach at line 249–251 from spy.mockClear() to spy.mockRestore(). That reinstalls the original getAddress after each test, so the next vi.spyOn creates a fresh spy exactly as before; the assertions and what they cover stay identical. The sibling file ledger-to-wallet-client.test.ts already does this (line 342) and passes under Vitest 4. A config-level test.restoreMocks: true is not a substitute: it would also undo the getName spy installed in beforeAll, so the ethereum describe would silently run against the default Celo app name.

Why I am not making that change: packages/viem-account-ledger/src is a protected path for the automated sweep (signing / key handling), so hand-written edits there, including test files, are reserved for a human. The branch is otherwise ready: rebased, lockfile consistent, provider versions matched. @pahor167 could you apply the one-line test change (or tell me if editing that test file is acceptable for the sweep) and remove the needs-human-merge label? The sweep will then take it through CI, Codex review and merge.

@pahor167 pahor167 added the needs-human-merge Dependency sweep could not green this PR within its allowed fixes label Oct 7, 2026
Vitest 4 removed the `coverage.all` option and its all-files default, so a
run that only sets `coverage.exclude` now reports just the files imported
during the tests. Source files no test touches silently vanish from the
LCOV upload instead of showing up with zero coverage, which inflates the
project numbers and lets untested additions slip past the patch check.

Setting `coverage.include` to the package's `src/**/*.ts` restores the
previous file set exactly: test files and setup files are still appended
to the exclude list by vitest itself, and the existing data, tokens and
test-utils excludes keep applying on top.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@pahor167

pahor167 commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Dependency sweep update (head 3ed763c):

Pushed this run: 3ed763c adds coverage.include: ['src/**/*.ts'] to the vitest configs of @celo/actions, @celo/core and @celo/viem-account-ledger. This addresses the second Codex finding: Vitest 4 dropped coverage.all, so without an explicit include only files imported during the run were reported and the Codecov project numbers shifted (161 → 101 files on the previous head). Verified locally that the LCOV file set with the include is exactly the package's non-test src/**/*.ts set minus the existing data/tokens/test-utils excludes, i.e. the same files Vitest 3 reported. The first Codex finding (matching @vitest/coverage-v8 version) was already handled by 32fc91c.

Still blocked on a human: the 7 failures in packages/viem-account-ledger/src/ledger-to-account.test.ts (respects the AddressValidation enum, both apps) remain. The one-line fix is spy.mockClear() → spy.mockRestore() in that file's afterEach (see my earlier comment for the root cause). That path is protected for the automated sweep, so @pahor167 please apply it and remove the needs-human-merge label; the sweep will then take the PR through CI, Codex and merge.

Lockfile, provider versions and rebase state are current; @celo/core and @celo/actions pass with coverage locally on this head.

@pahor167

pahor167 commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Dependency sweep status (head 3ed763c, current with master; nothing pushed today):

I looked for a fix outside the protected src/ path for the 7 respects the AddressValidation enum failures and ruled the options out. test.restoreMocks: true (or a setupFiles hook calling vi.restoreAllMocks()) would also strip the beforeAll spy on TestLedger.prototype.getName (ledger-to-account.test.ts:85-89) before every test and break the whole suite. clearMocks / mockReset run before beforeEach, so the getAddress call made by ledgerToAccount(...) in beforeEach is still counted and the off-by-one stays. The only correct fix remains spy.mockClear() → spy.mockRestore() in that file's afterEach (line 250), which the sweep may not edit.

Two more things need a human before this can merge, @pahor167:

  1. Resolve the two Codex threads on packages/actions/package.json (both addressed by 32fc91c and 3ed763c; replies are in the threads). The sweep never resolves reviewer threads itself and treats open Codex threads as findings, so even with the label removed it would not merge.
  2. codecov/project* is red for reasons unrelated to vitest: the base commit on master has no contractkit coverage (its ContractKit Tests (Anvil) job was cancelled after waiting 24h for a runner; I re-ran it today), the head has no vitest coverage because General vitest fails before the upload step, and CeloCli Tests (Anvil) retried 3 flaky suites via test-ci's --onlyFailures fallback, whose coverage output replaced the full run's and swung packages/cli numbers both ways (same line counts, different hits). Expect it to settle once the test fix lands and master coverage is complete; if it stays red, it is not this PR's doing.

Everything else is green on this head. The red Size checks entry is the cancelled ghost run 37727147358; the real Size checks (core) and Size checks (actions) pass.

@pahor167

Copy link
Copy Markdown
Contributor

Dependency sweep status (head 3ed763c, still current with master; nothing pushed today):

Re-verified on this head with a fresh local yarn install --immutable and yarn build:

  • Baseline yarn workspace @celo/viem-account-ledger test reproduces exactly the 7 CI failures in respects the AddressValidation enum (3 under celo, 4 under ethereum; expected 2 to be 1, 3 to be 2, 4 to be 3, 5 to be 1).
  • With the one-line change spy.mockClear() → spy.mockRestore() in the afterEach of packages/viem-account-ledger/src/ledger-to-account.test.ts (line 250) and nothing else: 4 files passed, 71 tests passed, 4 expected fail, 15 skipped. Fully green.
  • With test.restoreMocks: true in that package's vitest.config.ts instead (the only config-level candidate outside the protected path): it also restores the beforeAll spy on getName, so the ethereum block runs against the default app and 3 tests fail (signs typed data rejects with Not implemented as of this release., plus both cip64 cases). Not a substitute.

Context on the advisory: GHSA-82fw-gwwq-j7x9 (path traversal / arbitrary file read via @vitest/mocker) is patched only in vitest 4.1.11 and 5.0.0-rc.2. There is no 3.x fix, so staying on 3.2.6 is not an option, and this branch's lockfile already resolves to 4.1.11.

The test file is a protected path for the automated sweep, so that change has to come from a human. @pahor167: apply the one-liner, resolve the two Codex threads on packages/actions/package.json (both already addressed by 32fc91c and 3ed763c), and remove the needs-human-merge label; the sweep will then take the PR through CI, Codex and merge.

This branch has not been deployed

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

Labels

needs-human-merge Dependency sweep could not green this PR within its allowed fixes type:security

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant