yarnpkg/yarn · error · Error

Recursive .yarnrc files specifying --cwd flags. Bailing out.

Error message

Recursive .yarnrc files specifying --cwd flags. Bailing out.

What it means

When .yarnrc files chain --cwd flags into a cycle (A points to B, B points back to A), getRcArgs() detects the loop via previousCwds.indexOf(newCwd) !== -1 and bails. This prevents infinite recursion while following --cwd directives.

Source

Thrown at src/rc.js:138

}

// get a list of arguments from .yarnrc that apply to this commandName
export function getRcArgs(commandName: string, args: Array<string>, previousCwds?: Array<string> = []): Array<string> {
  // for the cwd, use the --cwd arg if it was passed or else use process.cwd()
  const origCwd = extractCwdArg(args) || process.cwd();

  // get a map of command names and their arguments
  const argMap = buildRcArgs(origCwd, args);

  // concat wildcard arguments and arguments meant for this specific command
  const newArgs = [...(argMap.get('*') || []), ...(argMap.get(commandName) || [])];

  // check if the .yarnrc args specified a cwd
  const newCwd = extractCwdArg(newArgs);
  if (newCwd && newCwd !== origCwd) {
    // ensure that we don't enter into a loop
    if (previousCwds.indexOf(newCwd) !== -1) {
      throw new Error(`Recursive .yarnrc files specifying --cwd flags. Bailing out.`);
    }

    //  if we have a new cwd then let's refetch the .yarnrc args relative to it
    return getRcArgs(commandName, newArgs, previousCwds.concat(origCwd));
  }

  return newArgs;
}

View on GitHub (pinned to c2dda503f3)

Solutions

  1. Inspect every .yarnrc in the chain and remove the circular --cwd entry
  2. Consolidate .yarnrc configuration into a single file
  3. Ensure no two .yarnrc files reference each other's directories via --cwd

Example fix

# before (.yarnrc in /proj/a)
--cwd ../b
# (.yarnrc in /proj/b)
--cwd ../a
# after — remove one reference
# (.yarnrc in /proj/b) — delete the --cwd line
Defensive patterns

Strategy: validation

Validate before calling

function detectCyclicCwd(yarnrcPaths, visited = new Set()) {
  for (const p of yarnrcPaths) {
    const cwd = extractCwdArg(parseYarnrc(p));
    if (cwd && visited.has(cwd)) return { cyclic: true, cwd };
    if (cwd) visited.add(cwd);
  }
  return { cyclic: false, cwd: null };
}

Type guard

function isCyclicCwdChain(previousCwds: string[], newCwd: string): boolean {
  return previousCwds.indexOf(newCwd) !== -1;
}

Try / catch

try {
  const args = getRcArgs(commandName, args);
} catch (e) {
  if (e.message.includes('Recursive .yarnrc')) {
    // fall back to a single explicit .yarnrc or skip --cwd
  }
}

Prevention

When it happens

Trigger: Two or more .yarnrc files each specify --cwd to a directory whose .yarnrc points back to a previously-visited cwd. previousCwds tracks the visited chain.

Common situations: Accidentally creating circular .yarnrc --cwd references; misconfigured monorepo setups; symlinks creating directory loops.

Related errors


AI-assisted analysis of yarnpkg/yarn@c2dda503f3 (2026-08-13). Data as JSON: /api/errors/fd00a15c6065fb7a. Report an issue: GitHub.