Skip to content

Fix diamond dependency double-import handling#553

Merged
philmillman merged 7 commits intomainfrom
copilot/fix-default-instance-initialization
Apr 7, 2026
Merged

Fix diamond dependency double-import handling#553
philmillman merged 7 commits intomainfrom
copilot/fix-default-instance-initialization

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 4, 2026

When the same schema directory is reachable via multiple import paths (diamond dependency), it was being fully loaded multiple times. This caused plugin init decorators (e.g. @initAws) to execute twice, crashing with "Instance with id '_default' already initialized".

Example topology that triggers the bug:

apps/console/.env.schema
  # @import(../../)              ← loads root (runs @plugin + @initAws)
  # @import(../shared-infra/)   ← loads shared-infra
    → shared-infra/@import(../../)  ← tries to load root again → 💥

Changes

  • EnvGraph — adds a private _loadedImportPaths: Set<string> and a checkAndRecordImportPath(path): boolean helper that atomically checks-and-records a path (returns true = already seen, skip it)
  • _processImports() — calls the helper before creating any DirectoryDataSource or DotEnvFileDataSource for all four import variants (virtual dir, virtual file, real dir, real file); skips with continue if the path was already loaded
  • Test plugin (test-plugin-with-init) — minimal plugin that registers an @initTestPlugin() root decorator with module-level singleton tracking, mirroring how real plugins like @varlock/aws-secrets-plugin behave
  • import.test.ts — three new diamond-dependency tests: directory dedup, directory dedup with a plugin init decorator, and file dedup

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • api.iconify.design
    • Triggering command: /opt/hostedtoolcache/node/24.14.1/x64/bin/node /opt/hostedtoolcache/node/24.14.1/x64/bin/node --experimental-import-meta-resolve --require /home/REDACTED/work/varlock/varlock/node_modules/.bun/vitest@4.1.0&#43;9d5cb286dd4627aa/node_modules/vitest/suppress-warnings.cjs --conditions node --conditions development /home/REDACTED/work/varlock/varlock/node_modules/.bun/vitest@4.1.0&#43;9d5cb286dd4627aa/node_modules/vitest/dist/workers/forks.js (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 4, 2026

🦋 Changeset detected

Latest commit: b89789c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 18 packages
Name Type
varlock Patch
@varlock/nextjs-integration Patch
@varlock/astro-integration Patch
@varlock/cloudflare-integration Patch
@varlock/expo-integration Patch
@varlock/vite-integration Patch
@varlock/1password-plugin Patch
@varlock/aws-secrets-plugin Patch
@varlock/azure-key-vault-plugin Patch
@varlock/bitwarden-plugin Patch
@varlock/dashlane-plugin Patch
@varlock/google-secret-manager-plugin Patch
@varlock/hashicorp-vault-plugin Patch
@varlock/infisical-plugin Patch
@varlock/keepass-plugin Patch
@varlock/pass-plugin Patch
@varlock/passbolt-plugin Patch
@varlock/proton-pass-plugin Patch

Not sure what this means? Click here to learn what changesets are.

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

Copilot AI linked an issue Apr 4, 2026 that may be closed by this pull request
Copilot AI and others added 2 commits April 4, 2026 12:17
When the same schema directory is imported via multiple paths (diamond
dependency), the schema file was being loaded twice. This caused plugin
init decorators (like @initAws) to run twice, throwing "Instance with id
'_default' already initialized".

Fix: Add _loadedImportPaths Set to EnvGraph to track already-loaded
import paths. Before adding a new DirectoryDataSource or
DotEnvFileDataSource for an import, check if the path was already
imported. If so, skip the duplicate import.

Also adds a test plugin (test-plugin-with-init) and three new tests in
import.test.ts covering the diamond dependency pattern for directory
imports, directory imports with plugins, and file imports.

Agent-Logs-Url: https://github.com/dmno-dev/varlock/sessions/a36fdb26-ef5a-41af-a057-cfa6d4d04f7c

Co-authored-by: philmillman <3722211+philmillman@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix instance with id '_default' already initialized error Fix "Instance with id '_default' already initialized" with diamond dependency imports Apr 4, 2026
Copilot AI requested a review from philmillman April 4, 2026 12:21
@philmillman philmillman requested a review from theoephraim April 4, 2026 12:24
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Apr 4, 2026

Open in StackBlitz

npm i https://pkg.pr.new/varlock@553
npm i https://pkg.pr.new/@varlock/nextjs-integration@553

commit: b89789c

@philmillman philmillman marked this pull request as ready for review April 4, 2026 12:27
@bestickley
Copy link
Copy Markdown

@philmillman, I tried out this PR package (super cool, by the way!) and it fixes #552! Thank you very much. Looking forward to this getting merged.

@philmillman
Copy link
Copy Markdown
Member

@philmillman, I tried out this PR package (super cool, by the way!) and it fixes #552! Thank you very much. Looking forward to this getting merged.

Ok thanks for testing! We'll get it out today or tomorrow at the latest

…and importKeys handling

The previous approach skipped duplicate imports entirely, which lost importKeys
from the second import and placed definitions at the wrong precedence position.

Now, duplicate imports create lightweight ImportAliasSource nodes in the tree.
These alias nodes share the original source's definitions but carry their own
importMeta/parent, giving them the correct position in the precedence chain.

A new sortedDefinitionSources list (derived from sortedDataSources by expanding
aliases) is used by ConfigItem.defs for item resolution, while sortedDataSources
remains unchanged for plugin init, error collection, and serialization.

Also adds type field to serialized source entries and updates the Next.js
integration to filter by type instead of label prefix.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@theoephraim theoephraim changed the title Fix "Instance with id '_default' already initialized" with diamond dependency imports Fix diamond dependency double-import handling Apr 7, 2026
theoephraim and others added 2 commits April 6, 2026 21:40
PR titles containing quotes broke the bash conditional. Using env vars
instead of inline interpolation prevents shell parsing issues.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The plugin tsconfig was missing node type definitions, causing typecheck
failures for any plugin importing node built-ins.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@philmillman philmillman merged commit 6ab2d31 into main Apr 7, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]: Instance with id "_default" already initialized

4 participants