Photo of Torben Hansen

A TechBlog by Torben Hansen


Freelance Full Stack Web Developer located in Germany.
I create web applications mainly using TYPO3, PHP, Python and JavaScript.
Home Archive Tags

How a wrong TCA configuration broke localization after updating to TYPO3 13.4

The initial problem

I have been doing a lot of TYPO3 major updates lately, and for one of the projects, a colleague of mine reported months later a strange problem with localization, which most likely is related to the update to TYPO3 13.4. The affected TYPO3 website contains a site which has two languages. The default language is german and the other language is English. The problem showed up when the user translated a record to english and some fields could not be translated anymore. Every time the user tried to save the translated record, the given translation for some fields was not saved, but the value of the original language was used.

Analysis and solution

To me this quickly sounded like a bug somewhere in the TCA of the affected table. So we started looking for possible misconfigurations in the TCA related to the localization, but everything was fine. Since the record was used in an TYPO3 inline field, we also started to look for possible misconfigurations in that direction but with no success. Finally, we looked at the TCA configuration for each field and found the following:

'title' => [
    'exclude' => true,
    'label' => 'LLL:EXT:sitepackage/Resources/Private/Language/locallang_tca.xlf:foo_table.title',
    'config' => [
        'type' => 'input',
        'size' => 50,
        'required' => true,
    ],
    'behaviour' => [
        'mode' => 'select',
        'allowLanguageSynchronization' => true,
    ],
],

The behaviour configuration for the field title is placed wrong, because it should be placed under config. Additionally, it contains the mode configuration, which is wrong too. After removing the behaviour configuration array, the problem was solved and the translations for affected fields were saved correctly again.

The wrong configuration has been there for a long time, and the problem first appeared after the update to TYPO3 13.4. The main question for me was: Why did the problem appear after the update and why can a wrong TCA configuration cause the described behavior?

In-depth analysis

The reason for this behavior lies deep in TYPO3s DataHandler and DataMapProcessor. When a record is saved in the backend, the DataHandler::process_datamap() function is called. This function calls the DataMapProcessor::process() function to process the submitted datamap and to sanitize/enrich the datamap with dependencies and localization states. The last part is interesting here, because it ensures that the allowLanguageSynchronization feature for fields is working correctly. The default behavior for allowLanguageSynchronization is to use the value of the original record as shown on the screenshot below.

TCA field with allowLanguageSynchronization

In this particular case, the sanitation in DataMapProcessor::process() resulted in the submitted field value for the title field being removed from the datamap. So somehow, the wrong TCA configuration for the field was taken into account when it comes to translation handling.

After some debugging with xdebug and with the help of some AI prompts, I found the culprit in the TCA schema. The reason why the wrong behaviour configuration suddenly took effect after the update to TYPO3 13.4 lies in the streamlineFieldConfiguration() function of FieldTypeFactory. The function removes the config array from the field configuration and merges its contents into the top-level field array. Before this schema processing was introduced in TYPO3 v13, the misplaced behaviour key at the top level was silently ignored. After the update, once config is flattened into the top level, the misplaced behaviour including allowLanguageSynchronization: true is now present in the merged result and picked up by DataMapProcessor when deciding how to handle field values during translation saving.

Learnings