{"record":{"id":"d58df7e6223a9f69","repo":"rectorphp/rector","slug":"provide-only-php-file-ready-for-dependency-inject","errorCode":null,"errorMessage":"Provide only PHP file, ready for Dependency Injection. \"%s\" given","messagePattern":"Provide only PHP file, ready for Dependency Injection\\. \"(.+?)\" given","errorType":"exception","errorClass":"ShouldNotHappenException","httpStatus":null,"severity":"error","filePath":"src/Caching/Config/FileHashComputer.php","lineNumber":26,"sourceCode":"use Rector\\Exception\\ShouldNotHappenException;\n/**\n * Inspired by https://github.com/symplify/easy-coding-standard/blob/e598ab54686e416788f28fcfe007fd08e0f371d9/packages/changed-files-detector/src/FileHashComputer.php\n */\nfinal class FileHashComputer\n{\n    public function compute(string $filePath): string\n    {\n        $this->ensureIsPhp($filePath);\n        $parametersHash = SimpleParameterProvider::hash();\n        return sha1($filePath . $parametersHash . VersionResolver::PACKAGE_VERSION);\n    }\n    private function ensureIsPhp(string $filePath): void\n    {\n        $fileExtension = pathinfo($filePath, \\PATHINFO_EXTENSION);\n        if ($fileExtension === 'php') {\n            return;\n        }\n        throw new ShouldNotHappenException(sprintf(\n            // getRealPath() cannot be used, as it breaks in phar\n            'Provide only PHP file, ready for Dependency Injection. \"%s\" given',\n            $filePath\n        ));\n    }\n}\n","sourceCodeStart":8,"sourceCodeEnd":33,"githubUrl":"https://github.com/rectorphp/rector/blob/408fcb0ff1833e3d26cbc9b04c23a77565814a16/src/Caching/Config/FileHashComputer.php#L8-L33","documentation":"FileHashComputer::compute() builds the cache key for the resolved Rector config file and asserts that file has a .php extension, since modern Rector configuration must be plain PHP. When ChangedFilesDetector::setFirstResolvedConfigFileInfo() passes a config path whose extension is not php, ensureIsPhp() throws ShouldNotHappenException. It is Rector telling you the file you pointed it at cannot be a Rector config.","triggerScenarios":"Running rector --config rector.yaml / rector.yml (legacy YAML config from Rector <=0.8), --config rector.dist, or a config file with any non-php extension; also a custom filename like rector-config.txt passed via --config.","commonSituations":"Projects migrating from old Rector versions that used YAML config; CI scripts still passing the ancient --config=rector.yml flag; config files renamed with a .dist or environment suffix.","solutions":["Convert the config to a PHP file named rector.php (or keep the .php extension, e.g. rector.dist.php)","Pass a .php config explicitly: vendor/bin/rector process src --config rector.php","Remove leftover YAML configs and update CI scripts/docs that reference them"],"exampleFix":"# before: legacy yaml config\nvendor/bin/rector process src --config rector.yml\n\n# after: php config\nvendor/bin/rector process src --config rector.php","handlingStrategy":"validation","validationCode":"// before running rector with an explicit config\n$configFile = getenv('RECTOR_CONFIG') ?: 'rector.php';\nif (pathinfo($configFile, PATHINFO_EXTENSION) !== 'php' || ! is_file($configFile)) {\n    fwrite(STDERR, \"Config must be an existing PHP file: {$configFile}\\n\");\n    exit(1);\n}","typeGuard":"function isPhpConfigFile(string $path): bool\n{\n    return pathinfo($path, PATHINFO_EXTENSION) === 'php' && is_file($path);\n}","tryCatchPattern":null,"preventionTips":["Keep the config named rector.php; if you need variants use .php suffixes (rector.ci.php)","Purge references to rector.yml from CI scripts and documentation during upgrades","When passing --config, lint the value in wrapper scripts before invoking rector"],"tags":["php","rector","config","yaml","file-extension","cache"],"backgroundTag":"unsupported-config-format","analyzedSha":"408fcb0ff1833e3d26cbc9b04c23a77565814a16","analyzedAt":"2026-08-21T05:11:02.643Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}