rectorphp/rector · error · ShouldNotHappenException
"%s" rule is deprecated, as the param type guessed from a si
Error message
"%s" rule is deprecated, as the param type guessed from a single array_map() closure is vague and unreliable. Add the @param docblock manually instead
What it means
Rector\TypeDeclarationDocblocks\Rector\ClassMethod\AddParamArrayDocblockBasedOnArrayMapRector is deprecated: refactor() throws Rector\Exception\ShouldNotHappenException on the first ClassMethod or Function_ node. The rule guessed a @param array<...> docblock for parameters consumed by a single array_map() closure, but a type inferred from one usage site is vague and unreliable as a contract for the whole parameter.
Source
Thrown at rules/TypeDeclarationDocblocks/Rector/ClassMethod/AddParamArrayDocblockBasedOnArrayMapRector.php:56
$names = array_map(fn(string $name) => trim($name), $names);
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [ClassMethod::class, Function_::class];
}
/**
* @param ClassMethod|Function_ $node
*/
public function refactor(Node $node): ?Node
{
throw new ShouldNotHappenException(sprintf('"%s" rule is deprecated, as the param type guessed from a single array_map() closure is vague and unreliable. Add the @param docblock manually instead', self::class));
}
}
View on GitHub (pinned to 408fcb0ff1)
Solutions
- Remove AddParamArrayDocblockBasedOnArrayMapRector from rector.php.
- Write the @param docblock manually where the accepted shape is actually known (check the callers).
- Prefer native param types plus explicit generics in one reviewed place over generated guesses.
Example fix
// before (rector.php) ->withRules([AddParamArrayDocblockBasedOnArrayMapRector::class]) // after (rector.php) - removed; write by hand /** * @param array<int, string> $names */ public function upperAll(array $names): array
Defensive patterns
Strategy: validation
Validate before calling
use Rector\TypeDeclarationDocblocks\Rector\ClassMethod\AddParamArrayDocblockBasedOnArrayMapRector;
$rules = [/* your list */ AddParamArrayDocblockBasedOnArrayMapRector::class];
if (in_array(AddParamArrayDocblockBasedOnArrayMapRector::class, $rules, true)) {
throw new InvalidArgumentException('Rule deprecated; write the @param docblock manually after checking callers');
} Try / catch
try {
exit($rectorApplication->run());
} catch (\Rector\Exception\ShouldNotHappenException $e) {
if (str_contains($e->getMessage(), 'AddParamArrayDocblockBasedOnArrayMapRector')) {
fwrite(STDERR, 'Remove the rule; a type guessed from one usage site is not a contract.' . PHP_EOL);
exit(1);
}
throw $e;
} Prevention
- Derive @param shapes from actual callers (PHPStan), not from one array_map usage.
- Keep docblock rules to a reviewed subset; the docblock-generation family was largely deprecated.
- Grep rector.php for 'TypeDeclarationDocblocks' after upgrades and diff against current docs.
When it happens
Trigger: The rule is still referenced in a TypeDeclarationDocblocks rule list and rector visits any method or function; refactor() throws on the first match.
Common situations: Enabling all TypeDeclarationDocblocks rules to raise PHPStan coverage; CI failing at the first method after a rector upgrade; leftover configs from experiments with docblock generation.
Related errors
- "%s" rule is deprecated, as too niche and of little practica
- "%s" rule is deprecated, as turning a docblock type into a r
- "%s" rule is deprecated, as removing an annotation by name i
- "%s" is deprecated as it has no real value
- "%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/656cedc63fbd528a.
Report an issue: GitHub.