rectorphp/rector · error · ShouldNotHappenException
"%s" rule is deprecated, as it is a personal preference that
Error message
"%s" rule is deprecated, as it is a personal preference that can move ternary values out of their logical order
What it means
SwitchNegatedTernaryRector used to reorder ternaries so the negated condition reads positively (swap $a ?: $b branches). It is deprecated because the reordering is a personal preference that can move the ternary's values out of their logical order and confuse readers. refactor() now throws ShouldNotHappenException on every Ternary node; the rule body is intentionally dead.
Source
Thrown at rules/CodeQuality/Rector/Ternary/SwitchNegatedTernaryRector.php:56
: $name;
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [Ternary::class];
}
/**
* @param Ternary $node
*/
public function refactor(Node $node): ?Node
{
throw new ShouldNotHappenException(sprintf('"%s" rule is deprecated, as it is a personal preference that can move ternary values out of their logical order', self::class));
}
}
View on GitHub (pinned to 408fcb0ff1)
Solutions
- Remove SwitchNegatedTernaryRector::class from rector.php and every imported set, then re-run vendor/bin/rector dry-run
- If a specific !condition ternary reads badly, invert that one site by hand
- Avoid mechanical branch swapping in team style — treat it as a review-time judgement
- Verify no custom set file re-adds the rule via grep -r SwitchNegatedTernaryRector
Example fix
// before (rector.php)
->withRules([
\Rector\CodeQuality\Rector\Ternary\SwitchNegatedTernaryRector::class,
])
// code:
$value = !$isOk ? 'fail' : 'pass';
// after (rector.php)
// rule removed
// code left alone, or inverted manually where it reads better:
$value = $isOk ? 'pass' : 'fail'; Defensive patterns
Strategy: validation
Validate before calling
$deprecated = ['SwitchNegatedTernaryRector'];
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
- Treat ternary branch order as a review preference, never an automated rewrite
- Prune the rule list in rector.php during every Rector upgrade
- Keep a fixture run in CI so deprecation guards fail the pipeline, not developers
- Do not re-add rules deleted from upstream sets into local configs
When it happens
Trigger: Registering rules/CodeQuality/Rector/Ternary/SwitchNegatedTernaryRector.php in the config and running rector over any file containing a ternary expression (?: or ? :). The throw comes from rules/CodeQuality/Rector/Ternary/SwitchNegatedTernaryRector.php:56 on the first ternary encountered.
Common situations: Stale rector.php rule lists or shared 'team standard' set files that still enumerate SwitchNegatedTernaryRector after upgrading rector/rector-prefixed. Since ternaries are ubiquitous, the first analysed file usually crashes.
Related errors
- "%s" is deprecated as depends on context and personal prefer
- "%s" rule is deprecated, as it is a personal preference that
- "%s" is deprecated, as simplifying regex ranges is a persona
- "%s" is deprecated, as match(true) with nested conditions is
- "%s" rule is deprecated, as it covers a very specific shape
AI-assisted analysis of rectorphp/rector@408fcb0ff1 (2026-08-21).
Data as JSON: /api/errors/61699d752634e5dc.
Report an issue: GitHub.