rectorphp/rector · error · ShouldNotHappenException
"%s" is deprecated, as it copies docblock from another metho
Error message
"%s" is deprecated, as it copies docblock from another method call that can be incorrect or outdated
What it means
Rector\TypeDeclarationDocblocks\Rector\ClassMethod\AddReturnDocblockFromMethodCallDocblockRector is deprecated: refactor() throws Rector\Exception\ShouldNotHappenException on the first ClassMethod node. The rule copied the @return docblock from another method call (e.g. the create() call inside the body) onto the enclosing method, but a copied docblock can be incorrect for the wrapper or become outdated when the inner method changes.
Source
Thrown at rules/TypeDeclarationDocblocks/Rector/ClassMethod/AddReturnDocblockFromMethodCallDocblockRector.php:77
// ...
}
}
CODE_SAMPLE
)]);
}
/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [ClassMethod::class];
}
/**
* @param ClassMethod $node
*/
public function refactor(Node $node): ?Node
{
throw new ShouldNotHappenException(sprintf('"%s" is deprecated, as it copies docblock from another method call that can be incorrect or outdated', self::class));
}
}
View on GitHub (pinned to 408fcb0ff1)
Solutions
- Remove AddReturnDocblockFromMethodCallDocblockRector from rector.php.
- Add the @return docblock manually where the wrapper's return type is genuinely the same, and keep it in sync on changes.
- Better: add a native return type or delegate the type via PHPStan generics instead of copying docblocks.
Example fix
// before (rector.php) ->withRules([AddReturnDocblockFromMethodCallRector::class]) // after (rector.php) - removed; write by hand /** * @return array<int, Item> */ public function createAll(): array
Defensive patterns
Strategy: validation
Validate before calling
use Rector\TypeDeclarationDocblocks\Rector\ClassMethod\AddReturnDocblockFromMethodCallDocblockRector;
$rules = [/* your list */ AddReturnDocblockFromMethodCallDocblockRector::class];
if (in_array(AddReturnDocblockFromMethodCallDocblockRector::class, $rules, true)) {
throw new InvalidArgumentException('Rule deprecated; do not copy docblocks between methods automatically');
} Try / catch
try {
exit($rectorApplication->run());
} catch (\Rector\Exception\ShouldNotHappenException $e) {
if (str_contains($e->getMessage(), 'AddReturnDocblockFromMethodCallDocblockRector')) {
fwrite(STDERR, 'Remove the rule; copied docblocks drift from the inner method.' . PHP_EOL);
exit(1);
}
throw $e;
} Prevention
- Give wrappers their own native return type or generics annotation instead of copying the inner method's docblock.
- When delegating types, rely on PHPStan's generics (@template/@T) rather than duplicated text.
- Remove deprecated docblock rules from rector.php during upgrade sweeps.
When it happens
Trigger: The rule is still listed in a TypeDeclarationDocblocks rule list and rector visits any class method; refactor() throws on the first ClassMethod match.
Common situations: Static-analysis coverage pushes that added docblocks everywhere; CI failing at the first factory-style method after a rector upgrade; docblocks drifting out of sync with the copied source method.
Related errors
- "%s" rule is deprecated, as too niche and of little practica
- "%s" rule is deprecated, as the array shape guessed from con
- "%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
AI-assisted analysis of rectorphp/rector@408fcb0ff1 (2026-08-21).
Data as JSON: /api/errors/7fec0c0e6130a71e.
Report an issue: GitHub.