rectorphp/rector · error · ShouldNotHappenException
"%s" rule is deprecated, as the #[Deprecated] attribute trig
Error message
"%s" rule is deprecated, as the #[Deprecated] attribute triggers a runtime deprecation, unlike the @deprecated annotation; use "phpstan/phpstan-deprecation-rules" to report the annotation instead
What it means
Rector\Php84\Rector\Class_\DeprecatedAnnotationToDeprecatedAttributeRector is deprecated: refactor() throws Rector\Exception\ShouldNotHappenException on the first Function_, ClassMethod or ClassConst node. The rule converted the passive @deprecated docblock annotation into the native #[Deprecated] attribute, but unlike the annotation the attribute triggers a real runtime deprecation notice whenever the element is called - a behavior change rector should not automate. The recommended replacement is the static-analysis package phpstan/phpstan-deprecation-rules, which reports @deprecated usage without runtime effects.
Source
Thrown at rules/Php84/Rector/Class_/DeprecatedAnnotationToDeprecatedAttributeRector.php:49
CODE_SAMPLE
, <<<'CODE_SAMPLE'
#[\Deprecated(message: 'Use SomeOtherFunction instead', since: '1.0.0')]
function someFunction()
{
}
CODE_SAMPLE
)]);
}
public function getNodeTypes(): array
{
return [Function_::class, ClassMethod::class, ClassConst::class];
}
/**
* @param ClassConst|Function_|ClassMethod $node
*/
public function refactor(Node $node): ?Node
{
throw new ShouldNotHappenException(sprintf('"%s" rule is deprecated, as the #[Deprecated] attribute triggers a runtime deprecation, unlike the @deprecated annotation; use "phpstan/phpstan-deprecation-rules" to report the annotation instead', self::class));
}
public function provideMinPhpVersion(): int
{
return PhpVersionFeature::DEPRECATED_ATTRIBUTE;
}
}
View on GitHub (pinned to 408fcb0ff1)
Solutions
- Remove DeprecatedAnnotationToDeprecatedAttributeRector from rector.php.
- Keep the @deprecated annotation and install phpstan/phpstan-deprecation-rules so PHPStan reports calls to deprecated code during static analysis.
- Only add #[Deprecated] by hand on the rare element where a runtime notice is explicitly wanted.
Example fix
// before (rector.php)
->withRules([
DeprecatedAnnotationToDeprecatedAttributeRector::class,
])
// after (rector.php) - rule removed; keep the annotation and check it statically
/**
* @deprecated use Mailer::send() instead
*/
// composer require --dev phpstan/phpstan-deprecation-rules Defensive patterns
Strategy: validation
Validate before calling
use Rector\Php84\Rector\Class_\DeprecatedAnnotationToDeprecatedAttributeRector;
$rules = [/* your list */ DeprecatedAnnotationToDeprecatedAttributeRector::class];
if (in_array(DeprecatedAnnotationToDeprecatedAttributeRector::class, $rules, true)) {
throw new InvalidArgumentException('Rule deprecated; use phpstan/phpstan-deprecation-rules instead');
} Try / catch
try {
exit($rectorApplication->run());
} catch (\Rector\Exception\ShouldNotHappenException $e) {
if (str_contains($e->getMessage(), 'DeprecatedAnnotationToDeprecatedAttributeRector')) {
fwrite(STDERR, 'Remove the rule; keep @deprecated and report usage via phpstan/phpstan-deprecation-rules.' . PHP_EOL);
exit(1);
}
throw $e;
} Prevention
- Before enabling PHP 8.4/8.5 rules wholesale, check the rule list against rector's current docs - deprecation-style rules were removed by design.
- Use static analysis (phpstan-deprecation-rules) for deprecation reporting; reserve #[Deprecated] for deliberate runtime notices.
- Grep rector.php for the rule class name after each rector upgrade.
When it happens
Trigger: The rule remains in rector.php (directly or copied from an old PHP 8.4 upgrade config) and rector visits any function, class method or class constant; refactor() throws on the first match.
Common situations: Running a PHP 8.4 level/set config built before the deprecation; CI failing right after a rector upgrade; teams wanting 'deprecated' warnings in CI without changing runtime behavior.
Related errors
- "%s" rule is deprecated, as the #[Deprecated] attribute trig
- The "%s" rule requires configuration.
- "%s" rule is deprecated, as property hooks are a matter of p
- The "->%s()" method is deprecated and no longer applied. Use
- E_USER_DEPRECATED
AI-assisted analysis of rectorphp/rector@408fcb0ff1 (2026-08-21).
Data as JSON: /api/errors/51ee7847c6d7b4d8.
Report an issue: GitHub.