rectorphp/rector · error · ShouldNotHappenException
"%s" rule is deprecated, as property hooks are a matter of p
Error message
"%s" rule is deprecated, as property hooks are a matter of preference. They provide no upgrade value and make the code harder to read
What it means
Rector\Php84\Rector\Class_\PropertyHookRector is deprecated: refactor() throws Rector\Exception\ShouldNotHappenException on the first Class_ node. The rule rewrote getter/setter method pairs into PHP 8.4 property hooks, but hooks are a stylistic preference with no upgrade value, and the mechanical rewrite often made classes harder to read. The rule requires PhpVersionFeature::PROPERTY_HOOKS, so it only loads on PHP 8.4+ targets.
Source
Thrown at rules/Php84/Rector/Class_/PropertyHookRector.php:60
{
get => $this->name;
set($value) => $this->name = ucfirst($value);
}
}
CODE_SAMPLE
)]);
}
public function getNodeTypes(): array
{
return [Class_::class];
}
/**
* @param Class_ $node
*/
public function refactor(Node $node): ?Node
{
throw new ShouldNotHappenException(sprintf('"%s" rule is deprecated, as property hooks are a matter of preference. They provide no upgrade value and make the code harder to read', self::class));
}
public function provideMinPhpVersion(): int
{
return PhpVersionFeature::PROPERTY_HOOKS;
}
}
View on GitHub (pinned to 408fcb0ff1)
Solutions
- Remove PropertyHookRector from rector.php; property hooks are opt-in style, not an upgrade step.
- If the team genuinely prefers hooks, convert specific getter/setter pairs by hand and review each diff in code review.
- Do not try to keep the rule via an older rector pin - it is intentionally gone.
Example fix
// before (rector.php)
->withRules([PropertyHookRector::class])
// after (rector.php) - removed; convert by hand where wanted
// manual, opt-in per case (PHP 8.4):
public string $name {
set => trim($value);
} Defensive patterns
Strategy: validation
Validate before calling
use Rector\Php84\Rector\Class_\PropertyHookRector;
$rules = [/* your list */ PropertyHookRector::class];
if (in_array(PropertyHookRector::class, $rules, true)) {
throw new InvalidArgumentException('PropertyHookRector is deprecated; property hooks are opt-in style, not an upgrade');
} Try / catch
try {
exit($rectorApplication->run());
} catch (\Rector\Exception\ShouldNotHappenException $e) {
if (str_contains($e->getMessage(), 'PropertyHookRector')) {
fwrite(STDERR, 'Remove the rule; convert getter/setter pairs to hooks manually where the team wants them.' . PHP_EOL);
exit(1);
}
throw $e;
} Prevention
- Decide property-hook adoption as a team style decision, then apply it by hand or in reviewed custom rules.
- Keep a curated rule allowlist in rector.php instead of wildcard PHP-version rule bundles.
- Remove deprecated rules immediately when rector reports them; leftover entries fail every later run.
When it happens
Trigger: The rule is still listed in a withPhp84()-style custom rule list or withRules() and rector visits any class declaration; refactor() throws immediately on the first Class_ node.
Common situations: Adopting a PHP 8.4 upgrade config copied from an older template; CI breaking after a rector upgrade that gutted the rule; teams that enabled it 'to try hooks' and forgot it in the config.
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/c11a6805e1bc6d6e.
Report an issue: GitHub.