---
title: "Breaking: #110286 - Text extractor registration and interface changed"
manual: "TYPO3 Core Changelog"
version: "main"
permalink: "https://docs.typo3.org/permalink/changelog:breaking-110286-1784879763"
source: "Changelog/15.0/Breaking-110286-TextExtractorRegistrationAndInterfaceChanged.rst"
typo3-version: "15.0"
typo3-major: 15
type: "breaking"
issue: 110286
forge: "https://forge.typo3.org/issues/110286"
tags: ["FAL", "PHP-API", "PartiallyScanned", "ext:core"]
rendered: "2026-10-07T19:18:07+00:00"
---

# Breaking: #110286 - Text extractor registration and interface changed {#breaking-110286-1784879763}

See [forge#110286](https://forge.typo3.org/issues/110286)

## Description {#description}

Text extractors are now registered as tagged services via dependency
injection (see [Feature: #110286 - Register text extractors as tagged services](https://docs.typo3.org/permalink/changelog:feature-110286-1784879763)). This comes with the
following breaking changes:

-   `\TYPO3\CMS\Core\Resource\TextExtraction\TextExtractorRegistry->registerTextExtractor()`
    is now a no-op. Calling the method has no effect anymore. The method
    will be removed in TYPO3 v16.0.
-   Extractors registered with the same priority are no longer
    guaranteed to be asked in the order they were added: previously,
    extractors kept the order in which
    `\TYPO3\CMS\Core\Resource\TextExtraction\TextExtractorRegistry->registerTextExtractor()` was called from
    [`ext_localconf.php`](https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ExtensionArchitecture/FileStructure/ExtLocalconf.html#file-extension-ext-localconf-php). The order of same-priority tagged services
    is now an implementation detail of the dependency injection container
    and must not be relied upon. Extensions that depend on a specific
    evaluation order between extractors should assign distinct priorities
    instead.
-   The methods of
    `\TYPO3\CMS\Core\Resource\TextExtraction\TextExtractorInterface`
    are now strictly typed: `canExtractText(FileInterface $file): bool`
    and `extractText(FileInterface $file): string`.
-   The method `createTextExtractorInstance()` has been removed
    from `\TYPO3\CMS\Core\Resource\TextExtraction\TextExtractorRegistry`, the method
    `getTextExtractorInstances()` has been changed from public to
    protected visibility, and the remaining methods are now strictly
    typed. The public API of the registry is
    `getTextExtractor()`, which returns the first matching
    extractor for a given file.

## Impact {#impact}

Text extractors registered via
`\TYPO3\CMS\Core\Resource\TextExtraction\TextExtractorRegistry->registerTextExtractor()` in
[`ext_localconf.php`](https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ExtensionArchitecture/FileStructure/ExtLocalconf.html#file-extension-ext-localconf-php) are no longer evaluated: no text is extracted
by the custom extractor until it is registered as a tagged service.

Custom extractor classes implementing `\TYPO3\CMS\Core\Resource\TextExtraction\TextExtractorInterface`
without the adapted method signatures will cause a fatal PHP error.

## Affected installations {#affected-installations}

All installations with custom extensions registering text extractors
via `\TYPO3\CMS\Core\Resource\TextExtraction\TextExtractorRegistry->registerTextExtractor()`, or providing
custom implementations of `\TYPO3\CMS\Core\Resource\TextExtraction\TextExtractorInterface`. The extension
scanner reports usages of `registerTextExtractor()` as a weak match.

## Migration {#migration}

Remove the `\TYPO3\CMS\Core\Resource\TextExtraction\TextExtractorRegistry->registerTextExtractor()` call
from [`ext_localconf.php`](https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ExtensionArchitecture/FileStructure/ExtLocalconf.html#file-extension-ext-localconf-php) and add the `#[AsTextExtractor]`
attribute to the extractor class instead. Add the native type
declarations to `canExtractText()` and `extractText()`:

**EXT:my_extension/Classes/Resource/TextExtraction/PdfTextExtractor.php**

```php
use TYPO3\CMS\Core\Attribute\AsTextExtractor;
use TYPO3\CMS\Core\Resource\FileInterface;
use TYPO3\CMS\Core\Resource\TextExtraction\TextExtractorInterface;

#[AsTextExtractor(priority: 10)]
final class PdfTextExtractor implements TextExtractorInterface
{
    public function canExtractText(FileInterface $file): bool
    {
        // ...
    }

    public function extractText(FileInterface $file): string
    {
        // ...
    }
}
```

In case the extension supports both TYPO3 v14 and v15, register the
extractor in both ways: the [`ext_localconf.php`](https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ExtensionArchitecture/FileStructure/ExtLocalconf.html#file-extension-ext-localconf-php) registration is
evaluated in v14, the attribute in v15. The `bool` and
`string` return type declarations are compatible with both
versions.

Code that called `\TYPO3\CMS\Core\Resource\TextExtraction\TextExtractorRegistry->getTextExtractorInstances()`
to inspect all registered extractors should inject
`\TYPO3\CMS\Core\Resource\TextExtraction\TextExtractorRegistry` and use `getTextExtractor($file)` to
retrieve the matching extractor for a given file instead.
