rectorphp/rector · error · ShouldNotHappenException
"%s" is deprecated as it worsens readability. Use "match (tr
Error message
"%s" is deprecated as it worsens readability. Use "match (true)" for the same logic instead
What it means
SwitchTrueToIfRector used to convert switch (true) { case ...: } constructs into if/elseif chains. It is deprecated because the rewrite worsens readability — PHP 8's match (true) expresses the same dispatch more compactly. refactor() now throws ShouldNotHappenException for every Switch_ node; the rule kept its class and constants only so outdated configurations abort instead of silently producing worse code.
Source
Thrown at rules/CodeQuality/Rector/Switch_/SwitchTrueToIfRector.php:69
}
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [Switch_::class];
}
/**
* @param Switch_ $node
*/
public function refactor(Node $node): ?Node
{
throw new ShouldNotHappenException(sprintf('"%s" is deprecated as it worsens readability. Use "match (true)" for the same logic instead', self::class));
}
}
View on GitHub (pinned to 408fcb0ff1)
Solutions
- Remove SwitchTrueToIfRector::class from rector.php / imported sets and re-run dry-run
- If you want to modernise switch (true), convert it manually to match (true) on PHP 8+
- Consider other still-supported switch rules (e.g. SwitchTrueToMatchRector if available in your version) instead
- Audit shared set packages for the deprecated class name
Example fix
// before (rector.php)
->withRules([
\Rector\CodeQuality\Rector\Switch_\SwitchTrueToIfRector::class,
]);
// code:
switch (true) {
case $x < 0: $label = 'neg'; break;
default: $label = 'pos';
}
// after (rector.php)
// rule removed
// code converted manually to match:
$label = match (true) {
$x < 0 => 'neg',
default => 'pos',
}; Defensive patterns
Strategy: validation
Validate before calling
$deprecated = ['SwitchTrueToIfRector'];
foreach (glob(__DIR__ . '/rector*.php') as $config) {
$src = file_get_contents($config);
foreach ($deprecated as $rule) {
if (str_contains($src, $rule)) {
fwrite(STDERR, "Remove deprecated rule {$rule} from {$config}\n");
exit(1);
}
}
} Prevention
- On PHP 8+, prefer match (true) over both switch(true) and if-chains
- Remove rules flagged deprecated in the version you upgrade to
- Test rector dry-run on a branch before merging the composer upgrade
- Convert dispatch constructs manually where readability demands it
When it happens
Trigger: Registering rules/CodeQuality/Rector/Switch_/SwitchTrueToIfRector.php in config and running process/dry-run over any file that contains a switch statement. The throw fires at rules/CodeQuality/Rector/Switch_/SwitchTrueToIfRector.php:69 on the first Switch_ node visited.
Common situations: Configs migrated from older Rector versions still list SwitchTrueToIfRector, or import an aged CodeQuality set that included it. Projects modernising to PHP 8 often kept this rule from a pre-match era, then hit the guard after a rector/rector-prefixed upgrade.
Related errors
- "%s" is deprecated, as match(true) with nested conditions is
- "%s" rule is deprecated, as turning a docblock type into a r
- "%s" rule is deprecated, as risky. The "??" and "?:" operato
- "%s" is deprecated as depends on context and personal prefer
- "%s" rule is deprecated, as it is a personal preference that
AI-assisted analysis of rectorphp/rector@408fcb0ff1 (2026-08-21).
Data as JSON: /api/errors/814a397017b27aa3.
Report an issue: GitHub.