rectorphp/rector · error · ShouldNotHappenException

"%s" rule is deprecated, as too niche and of little practica

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.

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)

Solutions

  1. Remove AddReturnArrayDocblockBasedOnArrayMapRector from rector.php.
  2. Where the item type genuinely helps (public APIs), write the @return docblock manually.
  3. 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

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


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