rectorphp/rector · error · ShouldNotHappenException

"%s" rule is deprecated, as the array shape guessed from con

Error message

"%s" rule is deprecated, as the array shape guessed from conditional assigns is vague and unreliable. Add the @return docblock manually instead

What it means

Rector\TypeDeclarationDocblocks\Rector\ClassMethod\AddReturnDocblockForDimFetchArrayFromAssignsRector is deprecated: refactor() throws Rector\Exception\ShouldNotHappenException on the first ClassMethod node. The rule reconstructed a @return array shape docblock from conditional dimension-fetch assignments ($row['key'] = ...), but an array shape guessed from assignments is vague and easily wrong once a branch is added or reordered.

Source

Thrown at rules/TypeDeclarationDocblocks/Rector/ClassMethod/AddReturnDocblockForDimFetchArrayFromAssignsRector.php:72

            $items['another_key'] = 'another_value';
        }

        return $items;
    }
}
CODE_SAMPLE
)]);
    }
    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 the array shape guessed from conditional assigns is vague and unreliable. Add the @return docblock manually instead', self::class));
    }
}

View on GitHub (pinned to 408fcb0ff1)

Solutions

  1. Remove AddReturnDocblockForDimFetchArrayFromAssignsRector from rector.php.
  2. Declare the array shape manually with a @return docblock (or a named value object/array shape type) where it is stable and useful.
  3. Where the shape keeps evolving, prefer a small DTO class over a docblock shape.

Example fix

// before (rector.php)
->withRules([AddReturnDocblockForDimFetchArrayFromAssignsRector::class])

// after (rector.php) - removed; write by hand

/**
 * @return array{id: int, name: string}
 */
public function buildRow(int $id): array
Defensive patterns

Strategy: validation

Validate before calling

use Rector\TypeDeclarationDocblocks\Rector\ClassMethod\AddReturnDocblockForDimFetchArrayFromAssignsRector;

$rules = [/* your list */ AddReturnDocblockForDimFetchArrayFromAssignsRector::class];
if (in_array(AddReturnDocblockForDimFetchArrayFromAssignsRector::class, $rules, true)) {
    throw new InvalidArgumentException('Rule deprecated; declare array shapes manually');
}

Try / catch

try {
    exit($rectorApplication->run());
} catch (\Rector\Exception\ShouldNotHappenException $e) {
    if (str_contains($e->getMessage(), 'AddReturnDocblockForDimFetchArrayFromAssignsRector')) {
        fwrite(STDERR, 'Remove the rule; shapes guessed from assignments go stale as code evolves.' . PHP_EOL);
        exit(1);
    }
    throw $e;
}

Prevention

When it happens

Trigger: The rule is still referenced in a TypeDeclarationDocblocks rule list and rector visits any class method; refactor() throws on the first ClassMethod match.

Common situations: Configs aiming for full PHPStan array-shape coverage; CI failing on the first method after a rector upgrade; legacy experiments where generated shapes later disagreed with reality.

Related errors


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