{"id":140,"date":"2026-11-05T08:00:00","date_gmt":"2026-11-05T07:00:00","guid":{"rendered":"https:\/\/hoja.in\/blog\/?p=140"},"modified":"2026-10-16T14:00:13","modified_gmt":"2026-10-16T12:00:13","slug":"asallowedcallable-in-typo3-v14-fixing-userfunc-errors","status":"publish","type":"post","link":"https:\/\/hoja.in\/blog\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\/","title":{"rendered":"#[AsAllowedCallable] in TYPO3 v14: fixing userFunc errors"},"content":{"rendered":"<p>You upgrade to TYPO3 v14, the backend looks fine, the start page renders, and then one page shows an error like this:<\/p>\n<pre><code class=\"language-text\">Attribute TYPO3CMSCoreAttributeAsAllowedCallable required for\ncallback reference: [\"Vendor\\Sitepackage\\UserFunc\\Copyright\",\"render\"]<\/code><\/pre>\n<p>Nothing changed in that class. It worked for years. What happened? In v14 the core changed the rules for which PHP methods TypoScript is allowed to call. This post explains the change, shows how to fix it properly, and how to find all affected places before your editors find them for you.<\/p>\n<h2>Why v14 restricts TypoScript callables<\/h2>\n<p>TypoScript can call PHP through <code>userFunc<\/code>, the <code>USER<\/code> and <code>USER_INT<\/code> content objects, and stdWrap properties like <code>preUserFunc<\/code> and <code>postUserFunc<\/code>. Before v14 any public method of any loadable class was fair game. TypoScript is written by integrators and sometimes stored in the database (sys_template records), so this was a wide door. If someone could change TypoScript, they could call PHP methods that were never meant for it.<\/p>\n<p><a href=\"https:\/\/docs.typo3.org\/c\/typo3\/cms-core\/main\/en-us\/Changelog\/14.0\/Breaking-108054-EnforceExplicitOpt-inForTypoScriptTSconfigCallables.html\">Breaking-108054<\/a> closes it with an explicit opt-in. A method is callable from TypoScript or TSconfig only if it carries the attribute <code>#[TYPO3CMSCoreAttributeAsAllowedCallable]<\/code>. According to the changelog this applies to:<\/p>\n<ul>\n<li>TypoScript <code>userFunc<\/code> processing, including <code>USER<\/code> and <code>USER_INT<\/code><\/li>\n<li>stdWrap <code>preUserFuncInt<\/code>, <code>postUserFunc<\/code> and <code>postUserFuncInt<\/code><\/li>\n<li>user functions in TypoScript constant comments<\/li>\n<li>TSconfig <code>renderFunc<\/code> of the suggest wizard<\/li>\n<\/ul>\n<p>The changelog list names <code>preUserFuncInt<\/code>, which I could not find as a stdWrap property in 14.3, and it does not name <code>preUserFunc<\/code>. But I looked at <code>ContentObjectRenderer<\/code> in 14.3: <code>stdWrap_preUserFunc()<\/code> goes through the same <code>callUserFunction()<\/code> method, which checks the attribute. So treat it the same. The check lives in <code>TYPO3CMSCoreSecurityAllowedCallableAssertion<\/code>, and the failure is an <code>AllowedCallableException<\/code>.<\/p>\n<p>Also note the index line of the changelog: <code>NotScanned<\/code>. The Extension Scanner will not warn you. You only notice at runtime, on the page which uses the function. That is why I was a bit shocked the first time.<\/p>\n<h2>Solution<\/h2>\n<h3>Step 1: add the attribute<\/h3>\n<p>The fix itself is one line per method:<\/p>\n<pre><code class=\"language-php\">&lt;?php\n\ndeclare(strict_types=1);\n\nnamespace VendorSitepackageUserFunc;\n\nuse PsrHttpMessageServerRequestInterface;\nuse TYPO3CMSCoreAttributeAsAllowedCallable;\n\nfinal class Copyright\n{\n    #[AsAllowedCallable]\n    public function render(string $content, array $conf, ServerRequestInterface $request): string\n    {\n        $from = (int)($conf['from'] ?? date('Y'));\n        $to = (int)date('Y');\n        return $from === $to ? (string)$to : $from . '\u2013' . $to;\n    }\n}<\/code><\/pre>\n<pre><code class=\"language-typoscript\">lib.copyright = USER\nlib.copyright {\n  userFunc = VendorSitepackageUserFuncCopyright-&gt;render\n  from = 2014\n}<\/code><\/pre>\n<p>The core calls the method with three arguments: the content, the TypoScript configuration array, and the request (with the current content object as request attribute <code>currentContentObject<\/code>). The attribute may sit on public instance methods, public static methods, public <code>__invoke()<\/code> methods and plain functions in the global namespace. Native PHP functions like <code>strtoupper<\/code> cannot get an attribute, so if your TypoScript calls one directly, you have to write a tiny wrapper function with the attribute.<\/p>\n<p>Usually the fix works right away: the container collects the attribute at build time, and the check falls back to reflection at runtime, so even a stale DI cache does not block it. If the error stays, first check that you edited exactly the class and method the error message names, then flush the caches anyway: <code>ddev typo3 cache:flush<\/code>.<\/p>\n<h3>Step 2: find every place before the editors do<\/h3>\n<p>Don&#8217;t wait for error reports. Grep the whole project for every TypoScript property that ends up in <code>callUserFunction()<\/code>:<\/p>\n<pre><code class=\"language-bash\"># TypoScript and TSconfig files in your own extensions and config\ngrep -rnE \"(userFunc|preUserFunc|postUserFunc|postUserFuncInt|renderFunc)s*=\" \n  Source\/Extension config\/sites packages 2&gt;\/dev\/null\n\n# TypoScript stored in the database (sys_template records)\nddev mysql -e \"SELECT uid, pid, title FROM sys_template \n  WHERE deleted = 0 AND (config LIKE '%UserFunc%' OR config LIKE '%userFunc%' OR constants LIKE '%userFunc%')\"<\/code><\/pre>\n<p>Adjust the paths to your project layout. Then list the unique class and method names and check each one. Third-party extensions are affected too: if the error points to a vendor class, look for an update of that extension before you patch anything.<\/p>\n<h3>Step 3: think before you mark<\/h3>\n<p>The point of the change is that you decide which methods are entry points. So please don&#8217;t blindly add the attribute everywhere. Ask for each method:<\/p>\n<ul>\n<li>Is it really meant to be called from TypoScript? Then add the attribute.<\/li>\n<li>Does it trust its <code>$conf<\/code> too much, for example by building SQL or file paths from it? Fix that first. With the attribute you are vouching for it.<\/li>\n<li>Is it legacy code that nobody uses anymore? Delete the TypoScript and the method. An upgrade is the best moment for this cleanup.<\/li>\n<\/ul>\n<h2>When a DataProcessor is the better tool<\/h2>\n<p>Many userFuncs I see in old projects do not render a string at all. They fetch some records, put them into an array, and a Fluid template renders them later through some trick. For that job, a DataProcessor is the right tool. It runs inside <code>FLUIDTEMPLATE<\/code> or <code>PAGEVIEW<\/code>, returns data to the view, and the template stays in charge of markup.<\/p>\n<p>DataProcessors are not affected by the new attribute check. The core only accepts classes that implement <code>DataProcessorInterface<\/code>, which is already an explicit contract. Here is a small one:<\/p>\n<pre><code class=\"language-php\">&lt;?php\n\ndeclare(strict_types=1);\n\nnamespace VendorSitepackageDataProcessing;\n\nuse TYPO3CMSFrontendContentObjectContentObjectRenderer;\nuse TYPO3CMSFrontendContentObjectDataProcessorInterface;\n\nfinal class CopyrightProcessor implements DataProcessorInterface\n{\n    public function process(\n        ContentObjectRenderer $cObj,\n        array $contentObjectConfiguration,\n        array $processorConfiguration,\n        array $processedData\n    ): array {\n        $from = (int)($processorConfiguration['from'] ?? date('Y'));\n        $as = $processorConfiguration['as'] ?? 'copyright';\n        $processedData[$as] = ['from' =&gt; $from, 'to' =&gt; (int)date('Y')];\n        return $processedData;\n    }\n}<\/code><\/pre>\n<pre><code class=\"language-yaml\"># Configuration\/Services.yaml\nservices:\n  VendorSitepackageDataProcessingCopyrightProcessor:\n    tags:\n      - name: data.processor\n        identifier: copyright<\/code><\/pre>\n<pre><code class=\"language-typoscript\">page = PAGE\npage.10 = PAGEVIEW\npage.10 {\n  paths.10 = EXT:sitepackage\/Resources\/Private\/PageView\/\n  dataProcessing.20 = copyright\n  dataProcessing.20.from = 2014\n}<\/code><\/pre>\n<p>In the template you write <code>{copyright.from}\u2013{copyright.to}<\/code>. The <code>data.processor<\/code> tag with an identifier is how the core registers its own processors (<code>files<\/code>, <code>menu<\/code>, <code>database-query<\/code> and so on); the full class name in TypoScript works too.<\/p>\n<p>My rule of thumb: a userFunc with the attribute for small strings that integrators place freely, like the copyright year. A DataProcessor whenever data goes to a Fluid template.<\/p>\n<h2>Supporting v13 and v14 in one extension<\/h2>\n<p>The attribute class does not exist in v13. That is not a problem: PHP only resolves an attribute class when someone calls <code>newInstance()<\/code> on it, and v13 never asks for this one. So you can add the <code>use<\/code> statement and the attribute in an extension that supports both lines. I would still run PHPStan against both versions to be sure your config does not complain about the unknown class.<\/p>\n<p>That&#8217;s all, folks. One line per method, but please make it a deliberate line. Cheers!<\/p>\n<h2>Further reading<\/h2>\n<ul>\n<li><a href=\"https:\/\/docs.typo3.org\/c\/typo3\/cms-core\/main\/en-us\/Changelog\/14.0\/Breaking-108054-EnforceExplicitOpt-inForTypoScriptTSconfigCallables.html\">Breaking-108054: Enforce explicit opt-in for TypoScript\/TSconfig callables<\/a><\/li>\n<li><a href=\"https:\/\/docs.typo3.org\/m\/typo3\/reference-typoscript\/main\/en-us\/ContentObjects\/UserAndUserInt\/Index.html\">TypoScript reference: USER and USER_INT<\/a><\/li>\n<li><a href=\"https:\/\/docs.typo3.org\/m\/typo3\/reference-typoscript\/main\/en-us\/DataProcessing\/Index.html\">TypoScript reference: Data processors<\/a><\/li>\n<li><a href=\"https:\/\/www.php.net\/manual\/en\/language.attributes.overview.php\">PHP manual: Attributes overview<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>After the v14 upgrade, TypoScript userFunc calls fail with AllowedCallableException. Why TYPO3 now wants an explicit opt-in, how to find every call, and when a DataProcessor is better.<\/p>\n","protected":false},"author":1,"featured_media":141,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17],"tags":[43,24,29,25],"class_list":["post-140","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-typo3","tag-security","tag-typo3-v14","tag-typoscript","tag-upgrades"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>TYPO3 v14 #[AsAllowedCallable]: fix userFunc errors<\/title>\n<meta name=\"description\" content=\"TYPO3 v14 requires #[AsAllowedCallable] on methods called from TypoScript userFunc and stdWrap. How to find and fix them, and when to use a DataProcessor.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/hoja.in\/blog\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"TYPO3 v14 #[AsAllowedCallable]: fix userFunc errors\" \/>\n<meta property=\"og:description\" content=\"TYPO3 v14 requires #[AsAllowedCallable] on methods called from TypoScript userFunc and stdWrap. How to find and fix them, and when to use a DataProcessor.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/hoja.in\/blog\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\/\" \/>\n<meta property=\"og:site_name\" content=\"Hoja Mustaffa Abdul Latheef \u2013 Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-11-05T07:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Hoja Mustaffa Abdul Latheef\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@hojaonline\" \/>\n<meta name=\"twitter:site\" content=\"@hojaonline\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Hoja Mustaffa Abdul Latheef\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\\\/\"},\"author\":{\"name\":\"Hoja Mustaffa Abdul Latheef\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/e6fbd54c2061674d8ea3e7861d858c7b\"},\"headline\":\"#[AsAllowedCallable] in TYPO3 v14: fixing userFunc errors\",\"datePublished\":\"2026-11-05T07:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\\\/\"},\"wordCount\":847,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/e6fbd54c2061674d8ea3e7861d858c7b\"},\"image\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/hoja.in\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors.jpg\",\"keywords\":[\"Security\",\"TYPO3 v14\",\"TypoScript\",\"Upgrades\"],\"articleSection\":[\"TYPO3\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/hoja.in\\\/blog\\\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\\\/\",\"url\":\"https:\\\/\\\/hoja.in\\\/blog\\\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\\\/\",\"name\":\"TYPO3 v14 #[AsAllowedCallable]: fix userFunc errors\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/hoja.in\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors.jpg\",\"datePublished\":\"2026-11-05T07:00:00+00:00\",\"description\":\"TYPO3 v14 requires #[AsAllowedCallable] on methods called from TypoScript userFunc and stdWrap. How to find and fix them, and when to use a DataProcessor.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/hoja.in\\\/blog\\\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\\\/#primaryimage\",\"url\":\"https:\\\/\\\/hoja.in\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors.jpg\",\"contentUrl\":\"https:\\\/\\\/hoja.in\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors.jpg\",\"width\":1200,\"height\":630,\"caption\":\"userFunc needs an opt-in now\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/hoja.in\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"#[AsAllowedCallable] in TYPO3 v14: fixing userFunc errors\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/hoja.in\\\/blog\\\/\",\"name\":\"Hoja Mustaffa Abdul Latheef \u2013 Blog\",\"description\":\"Notes from daily work with TYPO3, PHP and AI-assisted engineering\",\"publisher\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/e6fbd54c2061674d8ea3e7861d858c7b\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/hoja.in\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/e6fbd54c2061674d8ea3e7861d858c7b\",\"name\":\"Hoja Mustaffa Abdul Latheef\",\"logo\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/image\\\/\"},\"description\":\"Senior TYPO3 Developer at jweiland.net, TYPO3 CMS Certified Developer. I write about TYPO3 upgrades, extension development, PHP and AI-assisted engineering with Claude Code.\",\"sameAs\":[\"https:\\\/\\\/hoja.in\\\/\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"TYPO3 v14 #[AsAllowedCallable]: fix userFunc errors","description":"TYPO3 v14 requires #[AsAllowedCallable] on methods called from TypoScript userFunc and stdWrap. How to find and fix them, and when to use a DataProcessor.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/hoja.in\/blog\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\/","og_locale":"en_US","og_type":"article","og_title":"TYPO3 v14 #[AsAllowedCallable]: fix userFunc errors","og_description":"TYPO3 v14 requires #[AsAllowedCallable] on methods called from TypoScript userFunc and stdWrap. How to find and fix them, and when to use a DataProcessor.","og_url":"https:\/\/hoja.in\/blog\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\/","og_site_name":"Hoja Mustaffa Abdul Latheef \u2013 Blog","article_published_time":"2026-11-05T07:00:00+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors.jpg","type":"image\/jpeg"}],"author":"Hoja Mustaffa Abdul Latheef","twitter_card":"summary_large_image","twitter_creator":"@hojaonline","twitter_site":"@hojaonline","twitter_misc":{"Written by":"Hoja Mustaffa Abdul Latheef","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/hoja.in\/blog\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\/#article","isPartOf":{"@id":"https:\/\/hoja.in\/blog\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\/"},"author":{"name":"Hoja Mustaffa Abdul Latheef","@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/e6fbd54c2061674d8ea3e7861d858c7b"},"headline":"#[AsAllowedCallable] in TYPO3 v14: fixing userFunc errors","datePublished":"2026-11-05T07:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/hoja.in\/blog\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\/"},"wordCount":847,"commentCount":0,"publisher":{"@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/e6fbd54c2061674d8ea3e7861d858c7b"},"image":{"@id":"https:\/\/hoja.in\/blog\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\/#primaryimage"},"thumbnailUrl":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors.jpg","keywords":["Security","TYPO3 v14","TypoScript","Upgrades"],"articleSection":["TYPO3"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/hoja.in\/blog\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/hoja.in\/blog\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\/","url":"https:\/\/hoja.in\/blog\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\/","name":"TYPO3 v14 #[AsAllowedCallable]: fix userFunc errors","isPartOf":{"@id":"https:\/\/hoja.in\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/hoja.in\/blog\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\/#primaryimage"},"image":{"@id":"https:\/\/hoja.in\/blog\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\/#primaryimage"},"thumbnailUrl":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors.jpg","datePublished":"2026-11-05T07:00:00+00:00","description":"TYPO3 v14 requires #[AsAllowedCallable] on methods called from TypoScript userFunc and stdWrap. How to find and fix them, and when to use a DataProcessor.","breadcrumb":{"@id":"https:\/\/hoja.in\/blog\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/hoja.in\/blog\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/hoja.in\/blog\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\/#primaryimage","url":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors.jpg","contentUrl":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors.jpg","width":1200,"height":630,"caption":"userFunc needs an opt-in now"},{"@type":"BreadcrumbList","@id":"https:\/\/hoja.in\/blog\/asallowedcallable-in-typo3-v14-fixing-userfunc-errors\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/hoja.in\/blog\/"},{"@type":"ListItem","position":2,"name":"#[AsAllowedCallable] in TYPO3 v14: fixing userFunc errors"}]},{"@type":"WebSite","@id":"https:\/\/hoja.in\/blog\/#website","url":"https:\/\/hoja.in\/blog\/","name":"Hoja Mustaffa Abdul Latheef \u2013 Blog","description":"Notes from daily work with TYPO3, PHP and AI-assisted engineering","publisher":{"@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/e6fbd54c2061674d8ea3e7861d858c7b"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/hoja.in\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/e6fbd54c2061674d8ea3e7861d858c7b","name":"Hoja Mustaffa Abdul Latheef","logo":{"@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/image\/"},"description":"Senior TYPO3 Developer at jweiland.net, TYPO3 CMS Certified Developer. I write about TYPO3 upgrades, extension development, PHP and AI-assisted engineering with Claude Code.","sameAs":["https:\/\/hoja.in\/"]}]}},"_links":{"self":[{"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/posts\/140","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/comments?post=140"}],"version-history":[{"count":1,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/posts\/140\/revisions"}],"predecessor-version":[{"id":148,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/posts\/140\/revisions\/148"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/media\/141"}],"wp:attachment":[{"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/media?parent=140"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/categories?post=140"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/tags?post=140"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}