rectorphp/rector · error · ShouldNotHappenException
"%s" is deprecated, as null compare is ambiguous and weak; u
Error message
"%s" is deprecated, as null compare is ambiguous and weak; use an "instanceof" check instead
What it means
NullableCompareToNullRector used to rewrite loose object-vs-null comparisons such as if ($object != null) into stricter forms / null checks. It is deprecated because comparing objects against null with weak comparison is ambiguous (a falsy object vs a null object), and the intended check is usually $obj instanceof Foo — something a context-free rule cannot infer. refactor() now throws ShouldNotHappenException on every If_ node; the rule transforms nothing.
Source
Thrown at rules/CodingStyle/Rector/If_/NullableCompareToNullRector.php:50
if ($value === null) {
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [If_::class];
}
/**
* @param If_ $node
*/
public function refactor(Node $node): ?Node
{
throw new ShouldNotHappenException(sprintf('"%s" is deprecated, as null compare is ambiguous and weak; use an "instanceof" check instead', self::class));
}
}
View on GitHub (pinned to 408fcb0ff1)
Solutions
- Remove NullableCompareToNullRector::class from rector.php and all imported sets, then re-run dry-run
- Replace weak null comparisons by hand with the check you actually mean: $obj instanceof Foo, $obj !== null, or !empty($obj) as appropriate
- Enable strict_types and let static analysis (PHPStan level 6+) flag remaining weak comparisons
- grep -r NullableCompareToNullRector to eliminate every config reference
Example fix
// before (rector.php)
->withRules([
\Rector\CodingStyle\Rector\If_\NullableCompareToNullRector::class,
]);
// code:
if ($handler != null) {
$handler->run();
}
// after (rector.php)
// rule removed; manual fix expressing real intent:
if ($handler instanceof Handler) {
$handler->run();
} Defensive patterns
Strategy: validation
Validate before calling
$deprecated = ['NullableCompareToNullRector'];
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
- Replace weak null comparisons with instanceof or !== null by hand
- Declare strict_types and run PHPStan at high level to surface weak comparisons
- Remove deprecated rules from rector.php on every upgrade
- Validate configs with a CI dry-run before rolling Rector out
When it happens
Trigger: Registering rules/CodingStyle/Rector/If_/NullableCompareToNullRector.php and running rector over any file containing an if statement. The throw comes from rules/CodingStyle/Rector/If_/NullableCompareToNullRector.php:50 on the first If_ visited — effectively the first file analysed.
Common situations: Legacy rector.php rule lists or set bundles carried into a newer rector/rector-prefixed still name NullableCompareToNullRector. Since every procedural file has an if, the guard exception appears immediately and is frequently misdiagnosed as a vendor corruption issue.
Related errors
- "%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
- "%s" is deprecated, as simplifying regex ranges is a persona
AI-assisted analysis of rectorphp/rector@408fcb0ff1 (2026-08-21).
Data as JSON: /api/errors/ba136d6155b8bb9d.
Report an issue: GitHub.