rectorphp/rector · error · ShouldNotHappenException
"%s" is deprecated as noisy change with little value. Use ma
Error message
"%s" is deprecated as noisy change with little value. Use manually or custom rule where needed instead
What it means
StaticArrowFunctionRector used to prepend static to arrow functions (fn () => ... -> static fn () => ...) as a micro-optimisation preventing unwanted $this binding. It is deprecated as a noisy change with little value — it touches hundreds of call sites for a marginal, often irrelevant gain. refactor() now throws ShouldNotHappenException for every ArrowFunction node; the rule exists only to fail stale configs.
Source
Thrown at rules/CodingStyle/Rector/ArrowFunction/StaticArrowFunctionRector.php:40
CODE_SAMPLE
, <<<'CODE_SAMPLE'
static fn (): string => 'test';
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [ArrowFunction::class];
}
/**
* @param ArrowFunction $node
*/
public function refactor(Node $node): ?Node
{
throw new ShouldNotHappenException(sprintf('"%s" is deprecated as noisy change with little value. Use manually or custom rule where needed instead', self::class));
}
}
View on GitHub (pinned to 408fcb0ff1)
Solutions
- Remove StaticArrowFunctionRector::class from rector.php / imported sets and re-run dry-run
- Add static to the few arrow functions that are actually hot paths or leak-prone (event listeners, callbacks stored long-term), manually
- If you want blanket static closures, use PHP-CS-Fixer's static_lambda fixer instead of Rector
- Check for the rule name in any shared set package your config pulls in
Example fix
// before (rector.php)
->withRules([
\Rector\CodingStyle\Rector\ArrowFunction\StaticArrowFunctionRector::class,
])
// after
// rule removed; add static selectively by hand:
$callback = static fn (int $n): int => $n * 2; // only where binding must be prevented Defensive patterns
Strategy: validation
Validate before calling
$deprecated = ['StaticArrowFunctionRector'];
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
- Enforce blanket 'static' style with PHP-CS-Fixer static_lambda, not Rector
- Add static manually only to closures/arrow functions that must not bind $this
- Remove deprecated rules from config before upgrading rector/rector-prefixed
- Run a dry-run fixture in CI to catch tombstone rules immediately
When it happens
Trigger: Registering rules/CodingStyle/Rector/ArrowFunction/StaticArrowFunctionRector.php and running process/dry-run over any file containing a fn () => ... arrow function (PHP 7.4+ codebases). The throw fires at rules/CodingStyle/Rector/ArrowFunction/StaticArrowFunctionRector.php:40.
Common situations: Configs importing the CodingStyle set or listing this rule individually, carried into a newer Rector version where the rule was deprecated. Projects that adopted fn everywhere then upgraded rector/rector-prefixed crash on the first arrow function Rector visits.
Related errors
- "%s" is deprecated as noisy change with little value. Use ma
- "%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
AI-assisted analysis of rectorphp/rector@408fcb0ff1 (2026-08-21).
Data as JSON: /api/errors/844c3507382e0491.
Report an issue: GitHub.