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

  1. Remove StaticArrowFunctionRector::class from rector.php / imported sets and re-run dry-run
  2. Add static to the few arrow functions that are actually hot paths or leak-prone (event listeners, callbacks stored long-term), manually
  3. If you want blanket static closures, use PHP-CS-Fixer's static_lambda fixer instead of Rector
  4. 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

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


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