rectorphp/rector · error · ShouldNotHappenException
"%s" rule is deprecated, as it is a personal preference that
Error message
"%s" rule is deprecated, as it is a personal preference that makes array merges harder to read
What it means
ArraySpreadInsteadOfArrayMergeRector used to rewrite array_merge($a, $b) into [...$a, ...$b]. It is deprecated because the change is a personal preference that can make merges harder to read, and array_merge still differs from spread (string keys are overwritten rather than renumbered). refactor() now throws ShouldNotHappenException on every FuncCall node; the rule exists purely to fail configurations that still enable it.
Source
Thrown at rules/CodingStyle/Rector/FuncCall/ArraySpreadInsteadOfArrayMergeRector.php:61
$anotherValues = [...$iter1, ...$iter2];
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [FuncCall::class];
}
/**
* @param FuncCall $node
*/
public function refactor(Node $node): ?Node
{
throw new ShouldNotHappenException(sprintf('"%s" rule is deprecated, as it is a personal preference that makes array merges harder to read', self::class));
}
}
View on GitHub (pinned to 408fcb0ff1)
Solutions
- Remove ArraySpreadInsteadOfArrayMergeRector::class from rector.php and imported sets, then re-run dry-run
- Convert array_merge to spread manually only for hot paths with integer-keyed arrays
- Remember array_merge and spread are NOT equivalent for string keys — do not blindly swap
- If the style must be enforced, encode it in a review checklist or a scoped custom rule
Example fix
// before (rector.php)
->withRules([
\Rector\CodingStyle\Rector\FuncCall\ArraySpreadInsteadOfArrayMergeRector::class,
])
// code:
$all = array_merge($defaults, $overrides);
// after (rector.php)
// rule removed; manual conversion only where safe (integer keys):
$all = [...$defaults, ...$overrides];
// NOTE: with string keys, array_merge() and spread behave differently — keep array_merge() Defensive patterns
Strategy: validation
Validate before calling
$deprecated = ['ArraySpreadInsteadOfArrayMergeRector'];
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
- Remember spread and array_merge differ on string keys — never auto-swap
- Convert to spread manually only in measured hot paths
- Prune deprecated rules from rector.php before upgrading Rector
- Dry-run a fixture in CI so tombstone rules break the build, not a developer's run
When it happens
Trigger: Registering rules/CodingStyle/Rector/FuncCall/ArraySpreadInsteadOfArrayMergeRector.php and running rector over any file containing a function call. The throw comes from rules/CodingStyle/Rector/FuncCall/ArraySpreadInsteadOfArrayMergeRector.php:61 on the first FuncCall visited — effectively the first file.
Common situations: Configs that adopted the spread style for PHP 7.4+ performance still list this rule after upgrading rector/rector-prefixed. Since FuncCall matches every function call, the exception surfaces immediately and is often mistaken for a broken vendor directory.
Related errors
- "%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
- "%s" rule is deprecated, as it is a personal preference that
- "%s" rule is deprecated, as it covers a very specific shape
AI-assisted analysis of rectorphp/rector@408fcb0ff1 (2026-08-21).
Data as JSON: /api/errors/08732e3e4e58947f.
Report an issue: GitHub.