No Code Attached Yet bug
avatar LadySolveig
LadySolveig
29 Aug 2026

What happened?

  1. System → Site Templates → Cassiopeia → Details and Files, click Create Child Template, name it mychild.
  2. System → Site Template Styles, set "mychild - Default" as the default style.
  3. Back in mychild → Details and Files → Create Overrides → Modules → Articles - Categories. Joomla copies default.php and default_items.php into templates/mychild/html/mod_articles_categories/.
  4. In the file list of that override folder, rename default.php to tiles.php
  5. Content → Categories: make sure there is a published category with at least one published child category e.g. Parent with Child A under it. The module returns early when it has nothing to list, so without this the
    recursing line is never reached and the bug stays hidden.
  6. Content → Site Modules → New → Articles - Categories. Set Parent Category to Parent from step 5 and Depth to at least 1, so the module actually outputs a list. Set a position the template renders (e.g. sidebar-right), leave Status Published and Menu Assignment On all pages, then Advanced → Alternative Layout → "tiles". Joomla stores this as mychild:tiles. Save.
  7. Open any front-end page. The page does not render at all PHP aborts while building the module, before output starts, with the stack overflow.

Version

6.1

Expected result

The module renders, or fails with an error naming the layout it could not resolve.

Actual result

Maximum call stack size of 8339456 bytes (zend.max_allowed_stack_size -
zend.reserved_stack_size) reached. Infinite recursion?

The trace is modules/mod_articles_categories/tmpl/default.php:21 repeating until
the stack is exhausted.

Image

System Information

Joomla 6.1.3
PHP 8.5

Additional Comments

The same compose-and-require pattern appears six times in four core modules:

File Line
modules/mod_articles_categories/tmpl/default.php 21
modules/mod_articles_categories/tmpl/default_items.php 46
modules/mod_articles/tmpl/default.php 43
modules/mod_articles_category/tmpl/default.php 27
modules/mod_weblinks/tmpl/default.php 19
modules/mod_weblinks/tmpl/default_category.php 57

mod_articles_categories/tmpl/default_items.php calls it again, so that path can
loop across two files.

Originally found a different way: renaming a Cassiopeia child template.
Alternative layouts store the template name as a prefix (mychild:tiles), so every assignment points at a template that no longer exists after a rename, and the same recursion follows.

Either way the failure mode is the same, and it is the failure mode that seems wrong: a layout that cannot be resolved takes the whole site down instead of degrading.

avatar LadySolveig LadySolveig - open - 29 Aug 2026
avatar joomla-cms-bot joomla-cms-bot - change - 29 Aug 2026
Labels Added: No Code Attached Yet bug
avatar joomla-cms-bot joomla-cms-bot - labeled - 29 Aug 2026
avatar joomdonation
joomdonation - comment - 29 Aug 2026

You do not need to create child template to replicate the issue. You can just change this line of code https://github.com/joomla/joomla-cms/blob/6.2-dev/modules/mod_articles_categories/tmpl/default.php#L21 to something like:

<?php require ModuleHelper::getLayoutPath('mod_articles_categories', $params->get('layout', 'default') . '_items123'); ?>

Our ModuleHelper::getLayoutPath is defined to return the module default path if the path for the passed layout could not be found. In this case, ModuleHelper::getLayoutPath('mod_articles_categories', $params->get('layout', 'default') . '_items123'), the sub-layout could not be found, so the method just return the default layout path, which is current file and then the require command will cause infinite recursion

To prevent that, we need to check that returned path to make sure it is different with the path of the default layout before calling require command. But that will make the code unnecessary complicated, so I guess this will be a won't fix issue.

avatar LadySolveig
LadySolveig - comment - 29 Aug 2026

<?php require ModuleHelper::getLayoutPath('mod_articles_categories', $params->get('layout', 'default') . '_items'); ?>

At the very least, something like that would prevent the site from crashing completely, even if it doesn’t, of course, solve the problem at its root.

$layout_items = ModuleHelper::getLayoutPath('mod_articles_categories', $params->get('layout', 'default') . '_items');

if ($layout_items !== __FILE__) {
    require $items;
}
avatar LadySolveig
LadySolveig - comment - 29 Aug 2026

<?php require ModuleHelper::getLayoutPath('mod_articles_categories', $params->get('layout', 'default') . '_items'); ?>

At the very least, something like that would prevent the site from crashing completely, even if it doesn’t, of course, solve the problem at its root.

$layout_items = ModuleHelper::getLayoutPath('mod_articles_categories', $params->get('layout', 'default') . '_items');

if ($layout_items !== __FILE__) {
    require $items;
}

I just wanted to show-case a realistic scenario, just as it happened to me today. If it’s a ‘won’t fixed’ issue, at least it’s now documented in case anyone else runs into the same problem. 😊

avatar LadySolveig
LadySolveig - comment - 29 Aug 2026

<?php require ModuleHelper::getLayoutPath('mod_articles_categories', $params->get('layout', 'default') . '_items'); ?>

At the very least, something like that would prevent the site from crashing completely, even if it doesn’t, of course, solve the problem at its root.

$layout_items = ModuleHelper::getLayoutPath('mod_articles_categories', $params->get('layout', 'default') . '_items');

if (realpath($items) !== __FILE__) {
    require $items;
}

I just wanted to show-case a realistic scenario, just as it happened to me today. If it’s a ‘won’t fixed’ issue, at least it’s now documented in case anyone else runs into the same problem. 😊

avatar joomdonation
joomdonation - comment - 29 Aug 2026

You will need to add that ugly check to all module layouts which loads sub-layout like that, which is not something I would do :). In this case, the error happens just because of the wrong layout passed to second argument of the method call.
Maybe a new flag can be added to the method to not return default module layout pass of the passed layout is not found, but it is another discussion. This is still a special case, and still a won't fix for me.

avatar LadySolveig
LadySolveig - comment - 29 Aug 2026

If I’d had the time to get to work on it, I would have created a PR rather than an issue. You’re welcome to close it if you like. I think a notification would be nicer than having the page crash completely because of a module, but ultimately, the only thing that mattered to me was documenting it.

avatar joomdonation
joomdonation - comment - 29 Aug 2026

Please think about this as an open discussion. It's just my own opinion, let's wait to hear from others as well

(I agree that notification will be nicer, but it comes with certain cost which I think it is not worth for this)

avatar LadySolveig
LadySolveig - comment - 29 Aug 2026

That’s how I understood you too. If it came across the wrong way, it was a misunderstanding. :) I just wanted to make it clear that I’m not insisting on something here, and that ‘won’t fix’ is absolutely fine from my point of view too.

Add a Comment

Login with GitHub to post a comment