rectorphp/rector · error · ShouldNotHappenException

The installed package json not found. Make sure you run `com

Error message

The installed package json not found. Make sure you run `composer update` and the "vendor/composer/installed.json" file exists

What it means

InstalledPackageResolver::resolve() reads <project>/vendor/composer/installed.json (honoring a custom config.vendor-dir) to learn installed package versions; those versions drive version-bonded sets (e.g. rules targeting the installed symfony/http-foundation version) and ComposerBasedCommand. If the file does not exist it throws ShouldNotHappenException, meaning the project's dependencies were never installed in the directory Rector is running against.

Source

Thrown at src/Composer/InstalledPackageResolver.php:75

        // the previous file is no longer the source, drop what was read from it
        $this->resolvedInstalledPackages = null;
        $this->projectComposerJson = null;
    }
    /**
     * @return array<string, InstalledPackage>
     */
    public function resolve(): array
    {
        // already cached, even only empty array
        if ($this->resolvedInstalledPackages !== null) {
            return $this->resolvedInstalledPackages;
        }
        if ($this->composerJsonFilePath !== null) {
            return $this->resolvedInstalledPackages = $this->createPackagesFromConstraints();
        }
        $installedPackagesFilePath = $this->resolveVendorDir() . '/composer/installed.json';
        if (!file_exists($installedPackagesFilePath)) {
            throw new ShouldNotHappenException('The installed package json not found. Make sure you run `composer update` and the "vendor/composer/installed.json" file exists');
        }
        $installedPackageFileContents = FileSystem::read($installedPackagesFilePath);
        $installedPackagesFilePath = Json::decode($installedPackageFileContents, \true);
        $installedPackages = $this->createInstalledPackages($installedPackagesFilePath['packages']);
        $this->resolvedInstalledPackages = $installedPackages;
        return $installedPackages;
    }
    public function resolvePackageVersion(string $packageName): ?string
    {
        $package = $this->resolve()[$packageName] ?? null;
        if (!$package instanceof InstalledPackage) {
            return null;
        }
        return $package->getVersion();
    }
    /**
     * @param mixed[] $packages
     * @return array<string, InstalledPackage>

View on GitHub (pinned to 408fcb0ff1)

Solutions

  1. Run composer install (or composer update) in the project root so vendor/composer/installed.json exists
  2. Make sure you invoke rector from the directory that contains composer.json and vendor/ (check config.vendor-dir if customized)
  3. In CI, add the composer-install step before the rector step
  4. In monorepos, run rector per-package where the vendor lives, or point it at the package that owns the dependencies

Example fix

# before: CI runs rector on a fresh checkout
- run: vendor/bin/rector process src  # vendor/ not installed yet

# after: install dependencies first
- run: composer install --prefer-dist
- run: vendor/bin/rector process src
Defensive patterns

Strategy: validation

Validate before calling

// preflight before invoking rector
$vendorDir = 'vendor'; // adjust if composer config.vendor-dir is custom
if (! is_file($vendorDir . '/composer/installed.json')) {
    fwrite(STDERR, "Dependencies not installed; run `composer install` first\n");
    exit(1);
}

Try / catch

catch \Rector\Exception\ShouldNotHappenException in wrappers around rector; if the message mentions installed.json, run composer install and retry once.

Prevention

When it happens

Trigger: Running rector in a project where composer install/update has not been run (no vendor/), where vendor/ was pruned, where config.vendor-dir points elsewhere than where dependencies were installed, or where the phar is executed from a directory that is not the project root (wrong cwd).

Common situations: CI step order running rector before composer install; deployments that ship code without vendor; running the rector phar from a parent/monorepo directory while composer.json lives in a sub-package.

Related errors


AI-assisted analysis of rectorphp/rector@408fcb0ff1 (2026-08-21). Data as JSON: /api/errors/117ecf6bf53ea4e0. Report an issue: GitHub.