rectorphp/rector · error · ShouldNotHappenException
" " rule is deprecated, as splitting a single condition…
Error message
"%s" rule is deprecated, as splitting a single condition into multiple ifs makes the code longer and harder to read
What it means
Thrown when the deprecated ChangeOrIfContinueToMultiContinueRector rule executes. Its refactor() unconditionally throws ShouldNotHappenException because splitting a single `if (A || B) continue;` condition into multiple if-continue statements was judged to make code longer and harder to read. The class remains only so that stale configs referencing it fail loudly instead of silently doing nothing.
Solutions
- Delete the `ChangeOrIfContinueToMultiContinueRector::class` line from your rector config and re-run.
- Audit the config for the other deprecated EarlyReturn rules (ChangeNestedIfsToEarlyReturnRector, ReturnBinaryOrToEarlyReturnRector) and remove them together.
- If you want that specific transformation, apply it by hand or implement a small custom Rector rule in your project.
- As a stopgap, pin the previous Rector version that still shipped the working rule.
Example fix
// before - rector.php
$rectorConfig->rules([
\Rector\EarlyReturn\Rector\If_\ChangeOrIfContinueToMultiContinueRector::class,
]);
// after - registration removed; keep `if ($a || $b) { continue; }` as-is
// or split it manually where it genuinely reads better Defensive patterns
Strategy: validation
Validate before calling
$config = file_get_contents('rector.php');
if (strpos($config, 'ChangeOrIfContinueToMultiContinueRector') !== false) {
exit("Remove deprecated ChangeOrIfContinueToMultiContinueRector from rector.php before running rector.\n");
} Prevention
- Register rules via sets instead of one-by-one class names so deprecations cannot linger.
- Grep the config for 'EarlyReturn\\Rector' after upgrading rector; all three EarlyReturn rules in that namespace are deprecated throwers.
- Run rector on a small sample directory first when upgrading versions, so a stale rule fails fast in a cheap place.
When it happens
Trigger: `rector process` with a config that still registers `\Rector\EarlyReturn\Rector\If_\ChangeOrIfContinueToMultiContinueRector::class`. The rule declares getNodeTypes() = [If_::class], so the throw happens on the first `if` statement Rector visits in the analyzed codebase.
Common situations: Upgrading rector/rector across major versions with an unchanged rector.php that listed EarlyReturn rules one by one; reusing a legacy config file from another project; CI pipeline breaking right after a dependency update because the deprecated rule now throws instead of refactoring.
Related errors
- " " rule is deprecated, as inverting nested ifs to early…
- " " rule is deprecated, as splitting a single return into…
- " " is deprecated as risky change with little value. Use…
- Bootstrap file " " does not exist.
- Following rules are registered twice:
AI-assisted analysis of rectorphp/rector@408fcb0ff1 (2026-08-21).
Data as JSON: /api/errors/ab0a12d4806d5eaa.
Report an issue: GitHub.
Appendix: source
Thrown at rules/EarlyReturn/Rector/If_/ChangeOrIfContinueToMultiContinueRector.php:69
}
}
}
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" rule is deprecated, as splitting a single condition into multiple ifs makes the code longer and harder to read', self::class));
}
}
View on GitHub (pinned to 408fcb0ff1)