rectorphp/rector · error · ShouldNotHappenException
" " rule is deprecated, as too niche and of little…
Error message
"%s" rule is deprecated, as too niche and of little practical value. The item type is already known from the inline closure return type
What it means
Rector\TypeDeclaration\Rector\ClassMethod\AddReturnArrayDocblockBasedOnArrayMapRector is deprecated: refactor() throws Rector\Exception\ShouldNotHappenException on the first ClassMethod or Function_ node. The rule added an @return array<...> docblock inferred from an array_map() call in the body, but the item type is already visible in the inline closure's return type, so the generated docblock is redundant noise of little practical value.
Solutions
- Remove AddReturnArrayDocblockBasedOnArrayMapRector from rector.php.
- Where the item type genuinely helps (public APIs), write the @return docblock manually.
- Consider adding native return types or closure parameter types instead of relying on generated docblocks.
Example fix
// before (rector.php) ->withRules([AddReturnArrayDocblockBasedOnArrayMapRector::class]) // after (rector.php) - removed; add by hand where useful // manual, optional: /** * @return array<int, UserDto> */ public function mapUsers(array $rows): array
Defensive patterns
Strategy: validation
Validate before calling
use Rector\TypeDeclaration\Rector\ClassMethod\AddReturnArrayDocblockBasedOnArrayMapRector;
$rules = [/* your list */ AddReturnArrayDocblockBasedOnArrayMapRector::class];
if (in_array(AddReturnArrayDocblockBasedOnArrayMapRector::class, $rules, true)) {
throw new InvalidArgumentException('Rule deprecated; the item type is already visible in the array_map closure');
} Try / catch
try {
exit($rectorApplication->run());
} catch (\Rector\Exception\ShouldNotHappenException $e) {
if (str_contains($e->getMessage(), 'AddReturnArrayDocblockBasedOnArrayMapRector')) {
fwrite(STDERR, 'Remove the rule; add @return docblocks manually where they add value.' . PHP_EOL);
exit(1);
}
throw $e;
} Prevention
- Curate the TypeDeclaration rule list instead of enabling the whole set; several members are now deprecated stubs.
- Write @return docblocks for public APIs in the same PR that introduces the code.
- Check rector release notes for TypeDeclaration removals before upgrading shared configs.
When it happens
Trigger: The rule is still listed in a TypeDeclaration rule list in rector.php and rector visits any method or function; refactor() throws on the first ClassMethod/Function_ match.
Common situations: Bulk-enabling every TypeDeclaration rule for 'better types'; CI failing on the first analyzed method after a rector upgrade; configs shared between repositories that still carry the rule name.
Related errors
- " " is deprecated, as it copies docblock from another…
- " " rule is deprecated, as the param type guessed from a…
- " " is deprecated, as data provider docblock typing is not…
- " " is deprecated, as data provider docblock typing is not…
- " " is deprecated, as data provider docblock typing is not…
AI-assisted analysis of rectorphp/rector@408fcb0ff1 (2026-08-21).
Data as JSON: /api/errors/3058cd8a61454c67.
Report an issue: GitHub.
Appendix: source
Thrown at rules/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector.php:58
return array_map(function ($item): int {
return $item->id;
}, $items);
}
}
CODE_SAMPLE
)]);
}
public function getNodeTypes(): array
{
return [ClassMethod::class, Function_::class];
}
/**
* @param ClassMethod|Function_ $node
* @return null|\PhpParser\Node\Stmt\Function_|\PhpParser\Node\Stmt\ClassMethod
*/
public function refactor(Node $node)
{
throw new ShouldNotHappenException(sprintf('"%s" rule is deprecated, as too niche and of little practical value. The item type is already known from the inline closure return type', self::class));
}
}
View on GitHub (pinned to 408fcb0ff1)