Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Volta extends resolution in getNodeVersionFromFile has no cycle detection, recursing until stack overflow

Aperta
#1,628 3 commenti 0 reazioni 1 assegnatario Vedi su GitHub

I maintainer di solito rispondono entro 8 giorni

@v-gowridurgad ci sta già lavorando.

Dal 11/9/2026.

Valutazione

Questa issue non è ancora stata valutata.

Descrizione

Summary

getNodeVersionFromFile follows Volta extends recursively with no cycle detection, so a self-referential or mutually-referential volta.extends chain causes unbounded recursion and crashes the action with a stack overflow instead of a clear error.

Location

  • File: src/util.ts
  • Function: getNodeVersionFromFile(versionFilePath: string)
  • Code path:
if (manifest.volta?.extends) {
  const extendedFilePath = path.resolve(
    path.dirname(versionFilePath),
    manifest.volta.extends
  );
  core.info('Resolving node version from ' + extendedFilePath);
  return getNodeVersionFromFile(extendedFilePath);
}

No visited-path set or depth limit is threaded through the recursion.

Problem

Volta workspaces support {"volta": {"extends": "./base/package.json"}}. If the target (transitively) points back to a file already on the resolution stack — e.g. package.json with "extends": "./package.json" (typo), or a.json → b.json → a.json — the function recurses forever until V8 throws RangeError: Maximum call stack size exceeded. The user gets an opaque stack-overflow failure rather than a diagnostic naming the cycle.

Trigger / Reproduction

Based on static analysis (no workflow run performed):

  1. Set node-version-file to a package.json containing:
    {"volta": {"extends": "./package.json"}}
    
    or a two-file cycle a.json ↔ b.json via volta.extends.
  2. Run the action. getNodeVersionFromFile resolves extends, re-enters itself with the same path, and never terminates normally.

Note: this is a static-analysis finding; I did not execute a workflow against a cyclic fixture.

Expected Behavior

Cyclic volta.extends should fail fast with a clear error naming the files in the cycle (e.g. Detected cyclic volta.extends: a.json -> b.json -> a.json), consistent with how missing files already throw The specified node version file at: ... does not exist.

Actual Behavior

Unbounded recursion until stack exhaustion, producing an unactionable RangeError with no mention of the offending extends chain.

Impact

  • A one-character typo in volta.extends turns a configuration mistake into an opaque action crash, costing debugging time.
  • No data-loss risk, but the failure mode hides the actual cause (cycle) behind a generic engine error.

Suggested Direction

  • Thread a seen: Set<string> (resolved absolute paths) through getNodeVersionFromFile, checking before recursing and throwing a descriptive cycle error. Alternatively cap recursion depth with the same diagnostic. Either preserves current behavior for acyclic chains.

Evidence

  • Source via API: src/util.ts Volta-extends branch shows direct unconditional recursion with no guard; neighboring branches (missing file, non-JSON/TOML fallthrough) all have explicit handling, highlighting the gap.
  • Duplicate check: issue search for volta extends cycle recursion returns total_count: 0, and the open-issue list contains no extends-cycle report (nearest is .nvmrc comment parsing) — no apparent duplicate.
What happened

Unbounded recursion on cyclic Volta extends as detailed above.

Expected behavior

Fast, descriptive cycle error instead of stack overflow.

Steps to reproduce

Point node-version-file at a self- or mutually-referential Volta extends fixture and observe getNodeVersionFromFile re-enter indefinitely (static path; runtime stack overflow implied).

reproducible code
// package.json
{"volta": {"extends": "./package.json"}}
- uses: actions/setup-node@v4
  with:
    node-version-file: package.json
manifest.yaml

N/A

Versions
  • actions/setup-node: current main (verified via API, src/util.ts)
  • Node: N/A (static analysis finding)

Classification

  • FACT: Volta extends recursion has no visited-set or depth cap (verified in source via API).
  • INFERENCE: cyclic fixtures therefore recurse until stack exhaustion.
  • HYPOTHESIS: a visited-path guard produces a clear error with no change to valid chains.
Lingua principale
TypeScript
Stelle
5k
Fork
1.7k
Merge medio
13g 7h
PR unite (30g)
5

Preparare l'ambiente

  • Nessun Dockerfile né file Docker Compose
  • Ha un modello di pull request
  • Nessuna guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di actions/setup-node

Tutte le issue di actions/setup-node

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.