rectorphp/rector · error · ShouldNotHappenException

"%s" rule is deprecated, as splitting a single return into m

Error message

"%s" rule is deprecated, as splitting a single return into multiple early returns makes the code longer and harder to read

What it means

Thrown when the deprecated ReturnBinaryOrToEarlyReturnRector rule executes. Its refactor() unconditionally throws ShouldNotHappenException: splitting a single `return $a || $b;` into multiple early returns was judged to make code longer and harder to read, so the transformation was withdrawn while the class stays behind to make stale configs fail fast.

Source

Thrown at rules/EarlyReturn/Rector/Return_/ReturnBinaryOrToEarlyReturnRector.php:52

        if ($this->something()) {
            return true;
        }
        return (bool) $this->somethingElse();
    }
}
CODE_SAMPLE
)]);
    }
    /**
     * @return array<class-string<Node>>
     */
    public function getNodeTypes(): array
    {
        return NodeGroup::STMTS_AWARE;
    }
    public function refactor(Node $node): ?Node
    {
        throw new ShouldNotHappenException(sprintf('"%s" rule is deprecated, as splitting a single return into multiple early returns makes the code longer and harder to read', self::class));
    }
}

View on GitHub (pinned to 408fcb0ff1)

Solutions

  1. Remove the `ReturnBinaryOrToEarlyReturnRector::class` registration from your rector config and re-run.
  2. Remove the sibling deprecated EarlyReturn rules (ChangeNestedIfsToEarlyReturnRector, ChangeOrIfContinueToMultiContinueRector) in the same cleanup.
  3. If the early-return shape is wanted somewhere, refactor those returns manually or via a project-local custom rule.
  4. Short-term fallback: pin the last Rector release where this rule still worked.

Example fix

// before - rector.php
$rectorConfig->rule(\Rector\EarlyReturn\Rector\Return_\ReturnBinaryOrToEarlyReturnRector::class);

// after - no registration; keep `return $a || $b;` or split manually
Defensive patterns

Strategy: validation

Validate before calling

$config = file_get_contents('rector.php');
if (strpos($config, 'ReturnBinaryOrToEarlyReturnRector') !== false) {
    exit("Remove deprecated ReturnBinaryOrToEarlyReturnRector from rector.php before running rector.\n");
}

Prevention

When it happens

Trigger: `rector process` with a config that still registers `\Rector\EarlyReturn\Rector\Return_\ReturnBinaryOrToEarlyReturnRector::class`. Like its siblings it matches NodeGroup::STMTS_AWARE, so the very first function/method/loop body visited triggers the throw.

Common situations: Long-lived rector.php files carried across Rector major upgrades; configs assembled from copied snippets that enumerate EarlyReturn rules; CI failing after `composer update` because the rule now throws ShouldNotHappenException instead of rewriting returns.

Related errors


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