Skip to content

bug: stack overflow in earlyResolve() when env flag has circular dependencies #1

Description

@claude-do

Description

ConfigItem.earlyResolve() can cause a stack overflow (RangeError: Maximum call stack size exceeded) when the @currentEnv env flag item — or any item resolved early via @import enabled — has circular dependencies.

Root cause

earlyResolve() (packages/varlock/src/env-graph/lib/config-item.ts:272) recursively resolves dependency items without any termination guards:

  1. No idempotency check — unlike resolve() (which checks this.isResolved at line 468), earlyResolve() will re-enter items that have already been resolved, causing redundant work on diamond dependencies.
  2. No cycle detectionearlyResolve() runs during DataSource.finishInit(), which happens before EnvGraph.finishLoad() where findGraphCycles() is called (line 256). The normal cycle detection safety net does not exist yet at this point in the loading lifecycle.

If a circular dependency exists among items that participate in early resolution, the recursion has no termination condition and the process crashes.

Reproduction

# .env.schema
# @currentEnv=$APP_ENV
# ---
APP_ENV=$OTHER
OTHER=$APP_ENV

Running varlock run (or any command that loads this schema) crashes with RangeError: Maximum call stack size exceeded instead of reporting a schema error.

A self-referencing env flag (APP_ENV=$APP_ENV) also triggers the same crash.

Expected behavior

Circular dependencies in early-resolved items should produce a clear SchemaError / loading error, consistent with how cycles are reported during normal finishLoad() processing via findGraphCycles().

Affected code

  • packages/varlock/src/env-graph/lib/config-item.tsearlyResolve() method (line 272)
  • packages/varlock/src/env-graph/lib/data-source.ts — call sites at lines 149, 293, 704

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions