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

  1. Remove SwitchNegatedTernaryRector::class from rector.php and every imported set, then re-run vendor/bin/rector dry-run
  2. If a specific !condition ternary reads badly, invert that one site by hand
  3. Avoid mechanical branch swapping in team style — treat it as a review-time judgement
  4. 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

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


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