Repository navigation
Description
varlock version
varlock@1.24.0, @varlock/vite-integration@1.5.5. The same code is on main at 0ccee65. This is a regression in @varlock/vite-integration@1.5.0. 1.4.0 works.
Steps to reproduce
Reproduction: https://github.com/why-reproductions-are-required/varlock-vite-first-restart-stale-env
git clone https://github.com/why-reproductions-are-required/varlock-vite-first-restart-stale-env.git
cd varlock-vite-first-restart-stale-env
npm ci
npm run reproThe project is in app/. It has a .env.schema with GREETING=from-schema, a vite.config.js with varlockVitePlugin(), and a main.js that uses ENV.GREETING. The script runs vite app from the repository root, and then:
- Writes
GREETING=firsttoapp/.env.localand starts the dev server. - Changes
GREETINGtosecond. Vite printsapp/.env.local changed, restarting server.... - Changes
GREETINGtothird. Vite restarts again.
After each step, the script fetches /main.js and reads the value that the plugin inlined for ENV.GREETING.
To see it in a browser: run npx vite app, open the page, and change GREETING in app/.env.local. The page reloads with the old value. Change it again, and the page shows the newest value.
What is expected?
Every restart loads the new value: first, second, third.
What is actually happening?
The first restart keeps the old value. The second restart and all later restarts load correctly.
┌─────────┬─────────────┬──────────┬─────────┬─────────┐
│ (index) │ step │ expected │ actual │ result │
├─────────┼─────────────┼──────────┼─────────┼─────────┤
│ 0 │ 'start' │ 'first' │ 'first' │ 'ok' │
│ 1 │ 'restart 1' │ 'second' │ 'first' │ 'STALE' │
│ 2 │ 'restart 2' │ 'third' │ 'third' │ 'ok' │
└─────────┴─────────────┴──────────┴─────────┴─────────┘
CI runs three cases: https://github.com/why-reproductions-are-required/varlock-vite-first-restart-stale-env/actions/runs/40993856346
| Case | Command | Result |
|---|---|---|
| Root is not the working directory | npm run repro (vite app) |
stale |
rootDir set, _VARLOCK_ENV_KEY set |
npm run repro:root-dir |
stale |
Control: started from app/ |
npm run control (cd app && vite) |
ok |
System Info
@varlock/vite-integration 1.5.5, varlock 1.24.0, vite 8.3.5
Node.js 22 on ubuntu-latest (CI), Node.js 22.23.4 on macOS (local)Any additional comments?
Regression. This started in @varlock/vite-integration@1.5.0, with #985. npm run compare runs the same reproduction with varlock@1.17.1 and vite@8.3.5:
@varlock/vite-integration |
restart 1 value |
Result |
|---|---|---|
| 1.4.0 | second |
pass |
| 1.5.0 | first |
stale |
Before #985, the hook compared the root with process.cwd() (source). With vite app, the first branch reloaded on every call, restarts included. #985 compares with loadedConfigDir, so after the first reload, the first restart takes the !configHookCalled branch.
Cause. This is the config hook of inject-varlock-config (index.ts#L703-L718):
- The module-level
reloadConfig()loads fromprocess.cwd(), the repository root. - On the first
configcall,projectRoot(app/) differs fromloadedConfigDir, so the first branch reloads fromapp/. That branch does not setconfigHookCalled. - On the first restart, the module stays cached, and
projectRootnow equalsloadedConfigDir. The!configHookCalledbranch runs. It sets the flag and does not reload. - On the second restart, the
isDevCommandbranch reloads.
Why rootDir alone does not prevent it. Without _VARLOCK_ENV_KEY, rootDir hides the bug. The varlock-dev-key-lifecycle plugin calls ensureDevEncryptionKey(rootDir) (L277-L279). That call loads rootDir through getVarlockLoadedEnv() before the main config hook runs. When _VARLOCK_ENV_KEY is already set, ensureDevEncryptionKey() returns early, and the first restart is stale again.
Suggested fix. Set the flag in the first branch too:
if (rootDiffersFromLoaded) {
reloadConfig(projectRoot);
+ configHookCalled = true;
} else if (!configHookCalled) {With this change applied to dist/index.mjs, all three cases in the reproduction pass.
Activity
pullfrog commentedon Oct 30, 2026
[-][BUG]: Vite plugin keeps stale env values on the first dev server restart when Vite's root is not the working directory (regression in 1.5.0)[/-][+][BUG]: Vite plugin keeps stale env on first dev restart when root is not cwd[/+]github-actions commentedon Oct 30, 2026
✅ A fix has been merged to
mainin #1262 and will ship in the next release. GitHub auto-closed this issue on merge, but the change isn't published yet.