rectorphp/rector · info

E_USER_DEPRECATED

E_USER_DEPRECATED

Error message

UseNodesToAddCollector::%s is deprecated and will be removed. Use "%s" instead, via $file->getFileNode().

What it means

An E_USER_DEPRECATED is triggered (UseNodesToAddCollector::warn(), src/PostRector/Collector/UseNodesToAddCollector.php:213) whenever custom Rector rule or extension code calls one of the collector's legacy import methods: addUseImport(), addConstantUseImport(), addFunctionUseImport(), getUseImportTypesByNode(), hasImport(), isShortImported(), isImportShortable(), getObjectImportsByFilePath(), getConstantImportsByFilePath() or getFunctionImportsByFilePath(). The import/import-manipulation state moved from this global collector onto the per-file FileNode / PendingImports object, reachable via $file->getFileNode(). The old methods still work (they delegate internally) but only emit this notice and will be removed.

Solutions

  1. Refactor the call site to the FileNode API named in the message: get the current file via CurrentFileProvider (or the rule's refected file) and call $file->getFileNode()->getPendingImports()->addUseImport($type) (or addConstantUseImport/addFunctionUseImport) for writes.
  2. For read-style calls use the direct replacements: hasImport($type) -> $fileNode->hasImport($type); getUseImportTypesByNode() -> $fileNode->resolveUsedImportTypes(); isShortImported()/isImportShortable()/get*ImportsByFilePath() -> the matching getPendingImports() methods on FileNode.
  3. If the call comes from a third-party rule, check for an upgraded release of that package; otherwise pin rector/rector to the version the rule was built for until it is ported.
  4. If you must keep CI green while migrating, temporarily silence E_USER_DEPRECATED (error_reporting(E_ALL & ~E_USER_DEPRECATED) or PHPUnit convertDeprecationsToExceptions="false") - but treat it as a stopgap, the methods will be removed.

Example fix

// before
use Rector\PostRector\Collector\UseNodesToAddCollector;

$this->useNodesToAddCollector->addUseImport($className); // triggers E_USER_DEPRECATED

// after
use Rector\PostRector\Collector\UseNodesToAddCollector;
use Rector\Application\FileProcessor; // not needed; use current file provider instead
$file = $this->currentFileProvider->getFile();
$file->getFileNode()->getPendingImports()->addUseImport($className);
Defensive patterns

Strategy: validation

Validate before calling

// detect deprecated collector calls before running Rector, e.g. as a CI grep/PHPStan gate
$deprecated = [
    'addUseImport', 'addConstantUseImport', 'addFunctionUseImport',
    'getUseImportTypesByNode', 'hasImport', 'isShortImported', 'isImportShortable',
    'getObjectImportsByFilePath', 'getConstantImportsByFilePath', 'getFunctionImportsByFilePath',
];
// quick gate over custom rules:
foreach (glob('src/*Rector.php') as $file) {
    $code = file_get_contents($file);
    foreach ($deprecated as $method) {
        if (str_contains($code, 'useNodesToAddCollector->' . $method)) {
            fwrite(STDERR, "{$file} uses deprecated UseNodesToAddCollector::{$method}()\n");
        }
    }
}

Try / catch

// only as a stopgap while migrating: keep deprecations from failing PHPUnit/CI
set_error_handler(function (int $errno, string $errstr): bool {
    if ($errno === E_USER_DEPRECATED && str_contains($errstr, 'UseNodesToAddCollector::')) {
        return true; // suppress; log $errstr if needed
    }
    return false; // default handler
});

Prevention

When it happens

Trigger: Writing a custom Rector rule that injects UseNodesToAddCollector and calls e.g. $this->useNodesToAddCollector->addUseImport($type) to queue a `use` import; calling hasImport()/isShortImported() in a rule's conditions; reading current imports via getObjectImportsByFilePath(); running third-party/custom rules built against an older rector/rector API during `vendor/bin/rector process` - each legacy call site logs one deprecation line (often surfaced by PHPUnit or an error_handler converting E_USER_DEPRECATED to exceptions).

Common situations: Maintaining private/company Rector rules that were written for Rector 1.x and running them under a newer version; CI setups with convertDeprecationsToExceptions="true" in phpunit.xml or a strict error handler that turns the notice into a failing test; copied rule code from old blog posts or the Rector playbook using the collector to add imports.

Related errors


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

Appendix: source

Thrown at src/PostRector/Collector/UseNodesToAddCollector.php:213

    {
        $this->warn('getFunctionImportsByFilePath()', '$file->getFileNode()->getPendingImports()->getFunctionImports()');
        $fileNode = $this->resolveCurrentFileNode();
        if (!$fileNode instanceof FileNode) {
            return [];
        }
        return $fileNode->getPendingImports()->getFunctionImports();
    }
    private function resolveCurrentFileNode(): ?FileNode
    {
        $file = $this->currentFileProvider->getFile();
        if (!$file instanceof File) {
            return null;
        }
        return $file->getFileNode();
    }
    private function warn(string $method, string $replacement): void
    {
        trigger_error(sprintf('UseNodesToAddCollector::%s is deprecated and will be removed. Use "%s" instead, via $file->getFileNode().', $method, $replacement), \E_USER_DEPRECATED);
    }
}

View on GitHub (pinned to 408fcb0ff1)