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

  1. Remove SwitchTrueToIfRector::class from rector.php / imported sets and re-run dry-run
  2. If you want to modernise switch (true), convert it manually to match (true) on PHP 8+
  3. Consider other still-supported switch rules (e.g. SwitchTrueToMatchRector if available in your version) instead
  4. 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

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


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