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

"Attempt to insert record" error caused by PageDoktypeRegistry called in ext_localconf.php in TYPO3 13.4

TL;DR: After updating to TYPO3 13.4, if you see Attempt to insert record on pages:X where table "tt_content" is not allowed, it might be, that an extension is calling PageDoktypeRegistry::add() in ext_localconf.php instead of ext_tables.php. Move the call to ext_tables.php to fix it.

The problem

After updating a TYPO3 installation from 12.4 to 13.4, I could no longer save any content elements. TYPO3 always showed errors like:

Attempt to insert record on pages:1 where table "tt_content" is not allowed

Only a few hardcoded record types (like pages itself) could still be saved. Anything content-related on a standard page was blocked.

After some hours of debugging, I found out the reason for the problem. An extension was calling PageDoktypeRegistry::add() in ext_localconf.php instead of ext_tables.php. After moving the call to ext_tables.php, everything worked again.

In-depth analysis

I was curious why this happened, so I dug a little bit into the code.

TYPO3 12 introduced PageDoktypeRegistry as the central place to register which record tables are allowed on which page doktypes. The registry auto-discovers allowed tables from TCA on first use via an internal initializeTca() method, but only once. It sets a tcaHasBeenInitialized flag permanently for the current request lifecycle.

The problem is the boot order TYPO3 loads extension files:

  1. All ext_localconf.php files are executed. No TCA available yet
  2. TcaFactory compiles and populates $GLOBALS['TCA']
  3. All ext_tables.php files are executed. TCA is fully available

If any extension calls PageDoktypeRegistry::add() from ext_localconf.php, this triggers initializeTca() before TCA exists. The factory returns empty schemas, so no tables are auto-discovered from TCA (including tt_content), which relies on its 'security' => ['ignorePageTypeRestriction' => true] TCA configuration to be registered. Worse, the initialization lock is then permanently set, so when ext_tables.php runs later (correctly, after TCA is loaded), the auto-discovery step is silently skipped entirely.

The end state: tt_content is never added to the allowed tables for doktype 1 (standard page), and DataHandler::isTableAllowedOnPage() rejects every content element insert.