fix(varlock): allow @currentEnv to reference an imported key - #1066
Conversation
Peek unprocessed @import decorators during finishInit so an env flag that arrives via import does not error out before imports are merged. A values-only .env key still cannot act as the flag, imported directories load .env.<env> when the flag import is declared after them, and ancestor env propagation stops at a nested directory that set its own @currentEnv. Fixes #428
|
The changes in this PR will be included in the next version bump.
|
📦 Bundle size
dist/ only; native binaries are versioned separately and not counted here. |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
varlock-website | 57f9713 | Commit Preview URL Branch Preview URL |
Sep 03 2026, 07:17 AM |
There was a problem hiding this comment.
Important
Late environment backfill can leave imported directories initialized against the wrong values and produce loading errors.
Reviewed changes Checked the imported @currentEnv validation path, import-filter prediction, late environment-file propagation, documentation, and regression coverage.
- Imported flag recognition Defers
@currentEnvprocessing when a static import filter can provide the referenced key, then validates that the key actually arrived. - Environment source selection Prevents values found only in auto-loaded
.envfiles from independently satisfying the environment flag declaration. - Imported directory propagation Backfills
.env.<env>files into directories imported before the flag-providing import, while respecting nested@currentEnvboundaries. - Coverage and docs Adds eight environment-loading cases and updates the import and root-decorator documentation.
azure/gpt-5.6-sol | 𝕏
…king the AST Replace importStaticallyProvidesKey with a pending marker that is verified at the end of the file's own _processImports, so there is no parallel copy of the pick/omit/positional filter logic. Drop the post-hoc directory backfill: a directory imported before the flag is known now errors and asks for a reorder, since backfilling loaded its env files after its import conditions had already run. Give forEnv() before the flag import a clear message. Also let an imported @currentEnv carry through a partial import when the flag key passes the import filter, matching the existing full-import rule, and document the ordering limits in the import and monorepo guides.
@env-spec/parser
varlock
@varlock/native-helper-darwin
@varlock/native-helper-linux-arm64
@varlock/native-helper-linux-x64
@varlock/native-helper-win32-x64
@varlock/aws-sigv4-plugin
commit: |
There was a problem hiding this comment.
Important
Deferred flag validation is currently graph-wide, so an unrelated declaration can incorrectly satisfy @currentEnv.
Reviewed changes Reviewed the follow-up that replaced late directory backfill with import-order validation and deferred imported-flag checks.
- Deferred validation Checked the new post-import verification and clearer failure paths for missing flags and unresolved
forEnv()imports. - Directory ordering Verified that directories imported before the flag provider are now rejected instead of receiving environment files after initialization.
- Partial propagation Reviewed propagation of an imported
@currentEnvthrough partial imports when the flag key remains visible. - Coverage and docs Checked the added ordering and propagation cases plus the documented initialization constraints.
azure/gpt-5.6-sol | 𝕏
A declaration that reached the graph through another load path or an ancestor schema no longer satisfies a pending @currentEnv, so an omitted pick entry is still reported. Diamond aliases expand to their original so a re-imported shared file still counts.
There was a problem hiding this comment.
Important
Alias traversal can still accept a disabled declaration as the imported environment flag.
Reviewed changes Reviewed the source-scoped deferred flag validation added since the prior Pullfrog review.
- Scoped import validation Replaced the graph-wide declaration check with traversal of the declaring source's visible import subtree.
- Regression coverage Added multi-path, ancestor-schema, and diamond-alias cases for deferred
@currentEnvvalidation.
azure/gpt-5.6-sol | 𝕏
…ng env flag The alias node can be enabled while the original source was disabled by its own @disable, in which case its definitions are excluded from ConfigItem.defs and must not satisfy a pending @currentEnv either.
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes Reviewed the disabled-original handling added since the prior Pullfrog review.
- Alias disabled-state validation Checked the original source's effective disabled state after expanding an
ImportAliasSource, preventing a disabled declaration from satisfying a pending environment flag. - Regression coverage Added a diamond-import case where an enabled alias points to a source disabled by its own
@disable.
azure/gpt-5.6-sol | 𝕏
Follow-up to #1066: the environments guide still said the flag had to live in the same file. Co-authored-by: Kris Krüg <140290088+WalksWithASwagger@users.noreply.github.com>



Fixes #428.
Split 3 of 3 out of #1061 by @WalksWithASwagger, who wrote the original fix. The follow-up commit reshapes it; commit authorship is preserved on the first commit.
@currentEnv=$DEPLOY_ENVerrored whenever the flag arrived through@import, because the flag was validated duringfinishInit, before imports were merged. That breaks the monorepo shape in #428, where a sub-package imports a sharedDEPLOY_ENV.How it works
When
@currentEnvpoints at a key that is not defined in the file but the file has@imports, the check is deferred: the flag key is recorded, imports run, and at the end of that file's import processing we verify one of its own imports actually declared the key (scoped to that file's import subtree, so a declaration from another load path or an ancestor schema does not count). If none did, it errors and points atpick=[...]. The directory then loads.env.<env>files once the flag is known, the same path an imported@currentEnvalready used after #1050.Along with it:
.envvalue on its own no longer satisfies the flag or triggers.env.<env>loading.env.<env>files, or load them after its own import conditions had run)forEnv()in an import declared before the flag import gets a clear message instead of a TypeError@currentEnvdeclared in an imported file now also carries through a partial import when the flag key passes thepick/omitfilter, matching the existing full-import rule; an importer's own@currentEnvstill winsKnown limit (documented)
When the flag arrives via import, that file's
.env.<env>files load after its imports finish, so@import(enabled=...)and@disableconditions in that file cannot depend on values set only in those files. The import and monorepo guides explain the ordering and the workaround.Test plan
cd packages/varlock && bunx vitest run(1962 passed)bun run --filter @varlock/website buildenvironments.test.ts: pick, pick globs, positional keys, omitted flag, statically and dynamically disabled imports, flag import before/after a directory import, nested directory boundary, partial-import propagation of an imported@currentEnv(including vs--env), and the pending check staying scoped to the file's own imports (multi-path, ancestor schema, diamond alias, disabled alias original)