{"record":{"id":"88a8aa739e6ac93e","repo":"rectorphp/rector","slug":"s-rule-is-deprecated-as-it-is-a-personal-prefe","errorCode":null,"errorMessage":"\"%s\" rule is deprecated, as it is a personal preference that makes foreach harder to read and extend","messagePattern":"\"(.+?)\" rule is deprecated, as it is a personal preference that makes foreach harder to read and extend","errorType":"exception","errorClass":"ShouldNotHappenException","httpStatus":null,"severity":"error","filePath":"rules/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector.php","lineNumber":58,"sourceCode":"        }\n    }\n}\nCODE_SAMPLE\n)]);\n    }\n    /**\n     * @return array<class-string<Node>>\n     */\n    public function getNodeTypes(): array\n    {\n        return NodeGroup::STMTS_AWARE;\n    }\n    /**\n     * @param StmtsAware $node\n     */\n    public function refactor(Node $node): ?Node\n    {\n        throw new ShouldNotHappenException(sprintf('\"%s\" rule is deprecated, as it is a personal preference that makes foreach harder to read and extend', self::class));\n    }\n}\n","sourceCodeStart":40,"sourceCodeEnd":61,"githubUrl":"https://github.com/rectorphp/rector/blob/408fcb0ff1833e3d26cbc9b04c23a77565814a16/rules/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector.php#L40-L61","documentation":"UnusedForeachValueToArrayKeysRector used to rewrite foreach ($items as $key => $_) { ... } that ignores the value into foreach (array_keys($items) as $key) { ... }. It is deprecated because the transformation is a personal preference that makes the foreach harder to read and extend (you lose direct access to the value if the loop body grows). Its refactor() now throws ShouldNotHappenException on any StmtsAware node visit; the rule is dead code kept only to surface stale configuration.","triggerScenarios":"Registering rules/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector.php in the config and running process/dry-run over any statement-level node (the rule matches NodeGroup::STMTS_AWARE, i.e. functions, methods, namespaces — virtually every file). The throw comes from rules/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector.php:58.","commonSituations":"A legacy rector.php with a granular CodeQuality whitelist still naming this rule after a Rector upgrade. Because the node type is every statement container, the very first file analysed crashes, making it look like a Rector bug rather than a config problem.","solutions":["Remove UnusedForeachValueToArrayKeysRector::class from rector.php / imported sets and re-run dry-run","Leave foreach ($items as $key => $_) as is — it is perfectly readable and no upgrade requires changing it","If you prefer array_keys() style, convert the few sites manually","Check for the rule name in shared set packages your config imports"],"exampleFix":"// before (rector.php)\n->withRules([\n    \\Rector\\CodeQuality\\Rector\\Foreach_\\UnusedForeachValueToArrayKeysRector::class,\n])\n\n// after\n// rule deleted from config; loop style stays:\nforeach ($items as $key => $_) {\n    // uses $key only\n}","handlingStrategy":"validation","validationCode":"$deprecated = ['UnusedForeachValueToArrayKeysRector'];\nforeach (glob(__DIR__ . '/rector*.php') as $config) {\n    $src = file_get_contents($config);\n    foreach ($deprecated as $rule) {\n        if (str_contains($src, $rule)) {\n            fwrite(STDERR, \"Remove deprecated rule {$rule} from {$config}\\n\");\n            exit(1);\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check the Rector changelog when upgrading; remove rules marked deprecated the same day","Do not copy granular rule whitelists from tutorials; import curated sets instead","Keep foreach style decisions in code review, not in automated rewriting","Run vendor/bin/rector dry-run in CI to catch stale registrations before they hit developers"],"tags":["rector","php","deprecated-rule","foreach","code-style"],"backgroundTag":"rector-deprecated-rule","analyzedSha":"408fcb0ff1833e3d26cbc9b04c23a77565814a16","analyzedAt":"2026-08-21T05:11:02.643Z","schemaVersion":2},"datasetVersion":"2026-08-21T13:17:26.733Z"}