Yarn: `yarn install --frozen-lockfile` exits with error, but `yarn install` does nothing afterwards

Created on 25 Oct 2017  路  6Comments  路  Source: yarnpkg/yarn

Do you want to request a feature or report a bug?
Bug

What is the current behavior?

  1. Run yarn install with package.json present and no yarn.lock present.
  2. Immediately after run yarn install --frozen-lockfile
  3. Errors states that error Your lockfile needs to be updated, but yarn was run with --frozen-lockfile.
  4. Run yarn install again - no changes are made to yarn.lock

If the current behavior is a bug, please provide the steps to reproduce.

https://github.com/kompot/yarn-frozen-lockfile-bug

What is the expected behavior?
yarn install should fix yarn.lock so that it's up-to-date OR yarn --frozen-lockfile should not fail

Please mention your node.js, yarn and operating system version.
macOS 10.12.6
yarn 1.2.1
node 6.11

cat-bug high-priority triaged

Most helpful comment

Just an FYI for anyone else that hits this problem. For us it was because we had the same package listed in devDependencies and resolutions in the root package.json with different version numbers (forgot to update the devDependency). I didn't find this out until I ran through the yarn source code and put a console.log in this section:

      var match = yield this.integrityChecker.check(patterns, lockfileCache, this.flags, workspaceLayout);
      console.log('missingPatterns', match.missingPatterns)
      if (this.flags.frozenLockfile && (!lockfileClean || match.missingPatterns.length > 0)) {
        throw new (_errors || _load_errors()).MessageError(this.reporter.lang('frozenLockfileError'));
      }

That then clued us in to where to look. Maybe we should improve the frozen lockfile error message to include why it failed?

All 6 comments

From a quick glance, it looks like for some reason Yarn is reporting that babel-runtime@^6.26.0 is a missing pattern in the lockfile, but that pattern does exist:

[email protected], [email protected], babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0, babel-runtime@^6.5.0, babel-runtime@^6.9.2:
  version "6.26.0"
  resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
  dependencies:
    core-js "^2.4.0"
    regenerator-runtime "^0.11.0"

I'll continue digging in ...

More research notes:

It looks like what happens is that:

  • the lockfile is loaded and includes babel-runtime@^6.26.0

  • PackageResolver.resolveToResolution() removes a lot of entries from the lockfile, including babel-runtime@^6.26.0

  resolveToResolution(req: DependencyRequestPattern): ?DependencyRequestPattern {
    const {parentNames, pattern} = req;

    if (!parentNames || this.flat) {
      return req;
    }

    const resolution = this.resolutionMap.find(pattern, parentNames);

    if (resolution) {
      const resolutionManifest = this.getResolvedPattern(resolution);

      if (resolutionManifest) {
        invariant(resolutionManifest._reference, 'resolutions should have a resolved reference');
        resolutionManifest._reference.patterns.push(pattern);
        this.addPattern(pattern, resolutionManifest);
        this.lockfile.removePattern(pattern);
      } else {
        this.resolutionMap.addToDelayQueue(req);
      }
      return null;
    }

    return req;
  }
  • Then Yarn decides it needs to add babel-runtime@^6.26.0 back to the lockfile.

  • The --frozen-lockfile flag prevents this re-addition of babel-runtime@^6.26.0


This is because the package.json contains a resolution for babel-runtime:

  "resolutions": {
    "warning": "^3.0.0",
    "babel-runtime": "^6.26.0"
  }

If you delete the babel-runtime resolution, then yarn install --frozen-lockfile runs fine.


Summary: looks like a bug in the interaction between "resolutions" and frozen-lockfile.

Just an FYI for anyone else that hits this problem. For us it was because we had the same package listed in devDependencies and resolutions in the root package.json with different version numbers (forgot to update the devDependency). I didn't find this out until I ran through the yarn source code and put a console.log in this section:

      var match = yield this.integrityChecker.check(patterns, lockfileCache, this.flags, workspaceLayout);
      console.log('missingPatterns', match.missingPatterns)
      if (this.flags.frozenLockfile && (!lockfileClean || match.missingPatterns.length > 0)) {
        throw new (_errors || _load_errors()).MessageError(this.reporter.lang('frozenLockfileError'));
      }

That then clued us in to where to look. Maybe we should improve the frozen lockfile error message to include why it failed?

@BruceHubbard Omg thanks for this

@gaearon Sure thing, glad it helped someone.

I know this has been closed for a long time, but just wanted to +1 @BruceHubbard for the explanation of why this behaviours happens - just happened to me with 1.22.4. It was because in the package.json file there was a resolution on a different version of the one defined in dependencies and yarn can't seem to surface that error correctly but instead only kind of "interctly notices it" when doing a frozen install.

Was this page helpful?
0 / 5 - 0 ratings