rectorphp/rector · error · ShouldNotHappenException
"%s" rule is deprecated, as turning a docblock type into a r
Error message
"%s" rule is deprecated, as turning a docblock type into a runtime assert is risky and academic. Write a custom rule if the project needs it
What it means
AddAssertArrayFromClassMethodDocblockRector used to generate runtime Assert::allInteger()-style calls from @param array<int> docblocks on class methods. The rule is deprecated because converting a static docblock type into a runtime assertion is risky (docblocks are often incomplete) and of academic value only, so its refactor() now unconditionally throws ShouldNotHappenException. Hitting this error means your configuration still registers this dead rule: the class exists only so old configs can be discovered and flagged, it performs no transformation. The empty configure() body also means passing configuration no longer suppresses the throw.
Source
Thrown at rules/Assert/Rector/ClassMethod/AddAssertArrayFromClassMethodDocblockRector.php:61
*/
public function run(array $items)
{
Assert::allInteger($items);
}
}
CODE_SAMPLE
, ['Webmozart\Assert\Assert'])]);
}
public function getNodeTypes(): array
{
return [ClassMethod::class];
}
/**
* @param ClassMethod $node
*/
public function refactor(Node $node): ?ClassMethod
{
throw new ShouldNotHappenException(sprintf('"%s" rule is deprecated, as turning a docblock type into a runtime assert is risky and academic. Write a custom rule if the project needs it', self::class));
}
/**
* @param array<string> $configuration
*/
public function configure(array $configuration): void
{
}
}
View on GitHub (pinned to 408fcb0ff1)
Solutions
- Remove AddAssertArrayFromClassMethodDocblockRector::class from rector.php (and from any imported custom set), then re-run vendor/bin/rector dry-run
- If you genuinely need docblock-driven runtime asserts, write a project-specific custom rule implementing Rector\Rector\AbstractRector and register it locally
- Prefer verifying array shapes statically with PHPStan instead of injecting runtime asserts
- If the rule came from a bundled set, drop that set import and pick the rules you still want individually
Example fix
// before (rector.php)
return RectorConfig::configure()
->withRules([
AddAssertArrayFromClassMethodDocblockRector::class,
]);
// after
return RectorConfig::configure();
// need runtime asserts? enforce @param array<int> shapes in PHPStan instead, or write a custom rule Defensive patterns
Strategy: validation
Validate before calling
// before running rector, verify no deprecated rule is registered
$deprecated = ['AddAssertArrayFromClassMethodDocblockRector'];
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);
}
}
}
// safe to run: vendor/bin/rector dry-run Prevention
- Remove deprecated rules from rector.php before upgrading rector/rector-prefixed
- Run vendor/bin/rector dry-run on a single small path first so guard throws surface cheaply
- Keep custom rules in your own namespace so bundled-rule deprecations never break your config
- Read the Rector UPGRADING notes for each major version and prune your rule list accordingly
When it happens
Trigger: Registering rules/Assert/Rector/ClassMethod/AddAssertArrayFromClassMethodDocblockRector.php in rector.php (directly or via a set) and running vendor/bin/rector process or dry-run over any file that contains a ClassMethod node. The throw fires from refactor() at rules/Assert/Rector/ClassMethod/AddAssertArrayFromClassMethodDocblockRector.php:61 as soon as Rector visits the first matching node.
Common situations: Upgrading rector/rector-prefixed to a version where the Assert docblock rules were gutted, while rector.php still lists the rule in ->withRules([...]) or imports an old custom set file. Copying a rule list from an old blog post or another project's config also triggers it. Calling ->configure([...]) on the rule does not help — the method is now empty.
Related errors
- "%s" rule is deprecated, as removing an annotation by name i
- "%s" is deprecated as it has no real value
- "%s" rule is deprecated, as too niche and of little practica
- "%s" rule is deprecated, as the param type guessed from a si
- "%s" is deprecated, as data provider docblock typing is not
AI-assisted analysis of rectorphp/rector@408fcb0ff1 (2026-08-21).
Data as JSON: /api/errors/14876d64e70d1059.
Report an issue: GitHub.