rectorphp/rector · error · InvalidConfigurationException

We could not find local "composer.json" to determine your PH

Error message

We could not find local "composer.json" to determine your PHP version.%sPlease, fill the PHP version set in withPhpSets() manually.

What it means

ComposerJsonPhpVersionResolver::resolveFromCwdOrFail() infers the project's PHP version by reading getcwd() . '/composer.json' and its require.php entry. Despite the message wording, it throws both when composer.json is absent from the cwd AND when it exists but yields no integer PHP requirement (e.g. no require.php key).

Source

Thrown at src/Php/PhpVersionResolver/ComposerJsonPhpVersionResolver.php:33

{
    /**
     * @var array<string, PhpVersion::*|null>
     */
    private static array $cachedPhpVersions = [];
    /**
     * @return PhpVersion::*
     */
    public static function resolveFromCwdOrFail(): int
    {
        // use composer.json PHP version
        $projectComposerJsonFilePath = getcwd() . '/composer.json';
        if (file_exists($projectComposerJsonFilePath)) {
            $projectPhpVersion = self::resolve($projectComposerJsonFilePath);
            if (is_int($projectPhpVersion)) {
                return $projectPhpVersion;
            }
        }
        throw new InvalidConfigurationException(sprintf('We could not find local "composer.json" to determine your PHP version.%sPlease, fill the PHP version set in withPhpSets() manually.', \PHP_EOL));
    }
    /**
     * @return PhpVersion::*|null
     */
    public static function resolve(string $composerJson): ?int
    {
        if (array_key_exists($composerJson, self::$cachedPhpVersions)) {
            return self::$cachedPhpVersions[$composerJson];
        }
        $projectComposerJson = JsonFileSystem::readFilePath($composerJson);
        // give this one a priority, as more generic one. see https://github.com/composer/composer/issues/7914
        $requirePhpVersion = $projectComposerJson['require']['php'] ?? $projectComposerJson['require']['php-64bit'] ?? null;
        if ($requirePhpVersion !== null) {
            self::$cachedPhpVersions[$composerJson] = self::createIntVersionFromComposerVersion($requirePhpVersion);
            return self::$cachedPhpVersions[$composerJson];
        }
        // see https://getcomposer.org/doc/06-config.md#platform
        $platformPhp = $projectComposerJson['config']['platform']['php'] ?? null;

View on GitHub (pinned to 408fcb0ff1)

Solutions

  1. Run rector from the directory that contains composer.json (usually the project root)
  2. Add a php constraint to require: "require": {"php": "^8.2"}
  3. Or stop relying on autodetection: pin the level explicitly with withPhpSets(php82: true) / withPhpLevel(PhpVersion::PHP_82)

Example fix

// before: rector.php relies on cwd detection
return RectorConfig::configure()->withPhpSets();
// run from build/ -> throws

// after: explicit level, cwd no longer matters
use Rector\ValueObject\PhpVersion;

return RectorConfig::configure()->withPhpLevel(PhpVersion::PHP_82);
Defensive patterns

Strategy: validation

Validate before calling

// before relying on autodetection
$composerJsonPath = getcwd() . '/composer.json';
if (! is_file($composerJsonPath)) {
    throw new RuntimeException('Run Rector from the project root, or set an explicit PHP level.');
}
$require = json_decode((string) file_get_contents($composerJsonPath), true)['require'] ?? [];
if (! isset($require['php'])) {
    throw new RuntimeException('composer.json has no require.php; set withPhpLevel() explicitly.');
}

Prevention

When it happens

Trigger: Running vendor/bin/rector from a subdirectory or a directory without composer.json while rector.php calls withPhpSets() with no arguments; or a composer.json whose require section lacks a 'php'/'php-64bit' entry (e.g. only ext-* requirements).

Common situations: CI steps that cd into build/ or bin/ before invoking rector; monorepo tooling that executes from the workspace root while the config lives per-package; a library composer.json that never declared a php constraint.

Related errors


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