02 Jun 2026
Drupal.org aggregator
Freelock Blog: "Argo-nizing" Our Platform for AI Development
"Argo-nizing" Our Platform for AI Development

02 Jun 2026 5:00pm GMT
ComputerMinds.co.uk: Debugging Great Uncle Call Stacks - to solve a recursive router rebuild error

Our automated tests for a Drupal 11 upgrade failed with a cryptic error: Recursive router rebuild detected. A bit like when cron warns about it already running, this meant something had started a router rebuild, but without finishing successfully, before another rebuild of routing information was triggered. My solution was pretty specific to our context - but what might be interesting here is how I identified what had led to this problem.
The context
We run automated functional tests on this client project as regression tests, to show that various bespoke functionality still works, as changes are introduced. These are run in a DDEV instance inside a github action, via phpunit (and the DDEV Selenium Standalone Chrome add-on). To keep the maintenance of these tests easy and as portable as possible, we just use core's existing phpunit.xml.dist file as their configuration. The tests install a fresh Drupal site, importing our project's ordinary configuration along the way, and then perform actions in a headless browser, clicking on elements just like a site visitor would, etc. During work to upgrade from Drupal 10 to 11, tests started failing whilst just installing Drupal. Nothing to do with our custom functionality. What gives?!
The easy bit
At least we had a clear error message to go by. Enable xdebug, stick a breakpoint on the line which throws the exception, and run to the line. (Thanks DDEV for getting us that far easily enough!) So that's in the rebuild() method of core's \Drupal\Core\Routing\RouteBuilder class. Simple enough to confirm there that, yes, the $this->building property shows a previous attempt to rebuild the routes has happened. But how can we see what that was?
At this point, the call stack shows us all the 'parent' callers of this method, but it's not a truly recursive call like the error implies: there's no smoking gun suggesting something incorrectly called back into rebuild(). Traversing through the parents, the most notable thing was just to see that this call is part of the install_finished step of installing Drupal. Seems reasonable that Drupal would build up its record of routes once everything has been installed. So what earlier installation task had somehow started a router rebuild, without getting to the end of the rebuild() method where the $this->building property is reset?
I wanted to identify what had triggered the earlier incomplete router rebuild, regardless of why that hadn't completed successfully. (In post-mortem, I found some unrelated exception had been thrown, sending control flow away before the $this->building property was reset, but the exception was handled 'gracefully' and installation innoncently continued. That exception could be avoided, but the principle remains that some kinds of exception should be acceptable and allow installation to continue on successfully.)
The magic
So the parent function calls, and 'grandparent' calls, couldn't tell me much. If the function stacks were CSS, I'd be building mad :has() selectors for the previous sibling of a grandparent (or some other ancestor). Something like a Great Uncle or Great Aunt, perhaps? Anyway - let's call it that - I needed to debug the Great Uncle Stack!
The diagram above illustrate this, as a graph of control flow (to be read depth-first, left-to-right). The exception is only thrown on the second call to rebuild() (the right branch in the diagram), but the call we need to understand is at the end of the first stack (the left branch), which wouldn't be available to us during the second call. We want to know what triggered that first rebuild() call.
Here's how I solved this: use a static variable to record each previous entry into the method; i.e. the full stack traces, with PHP's internal debug_backtrace() function:
static $stacks = [];
$stacks[] = debug_backtrace();
Then during the breakpoint debugging session, that static store of stack traces can be inspected.
So when my breakpoint landed, I could then see what the call stack was for when this rebuild() method had been previously called! In the screenshot above, the $stacks variable holds two stack traces: the first will contain the cause of the mysterious first failed call to rebuild(), somewhere in its stack of 42 function calls. (The second value in $stacks is just the stack trace up to this breakpoint, about to throw the exception.) So traversing through that first stack showed a specific install task and function that had triggered this.
The surprise
Bizarrely, the culprit was core's menu_link_content module! It has an entity_predelete hook implementation which, quite sensibly, wants to remove any menu links pointing to entities being deleted. But to do that, of course it needs to get information about which URLs an entity has which a menu link could point to - and that means route information is needed.
Of course, whilst installing Drupal, we didn't have any such menu links we needed to care about! But we do have entities that get deleted, so that hook is invoked. Our ordinary configuration for the project is imported as part of installing Drupal, which actually recreates some config - i.e. deleting before creating again the same config, just with a different UUID. That's because various config is created by default in installations without a specific UUID, and then gets switched to match the UUIDs in the config for our project.
Some of that config is created by Drupal core itself - for example, date formats from the system module - and others from quite reliable modules, like token. We could go round patching each individually to avoid them installing config that we will only recreate later during installation. But that wouldn't be very maintainable, and doesn't respect the quite reasonable default installation process.
Instead we crippled the specific functionality for finding menu links to delete, just during installation, with a simple hook_module_implements_alter():
/** * Implements hook_module_implements_alter(). */ function MYPROFILE_module_implements_alter(&$implementations, $hook) { if ($hook === 'entity_predelete') { // During site installation, we have no menu links to clear up. Avoid // menu_link_content triggering router rebuilds on deleting entities.try { if ( function_exists('install_verify_completed_task') && install_verify_completed_task() ) { unset($implementations['menu_link_content']); } } catch (\Drupal\Core\Installer\Exception\AlreadyInstalledException $e) { // Allow menu_link_content to react to entity deletion. } } }
Our automated tests now pass, with Drupal installing successfully. Mystery solved and new debugging technique unlocked!
02 Jun 2026 3:26pm GMT
ImageX: Higher Education Website Best Practices: A Guide to Strategy, Design, and Development
02 Jun 2026 1:23pm GMT
25 May 2026
W3C - Blog
W3C Japan Member Meeting and W3C in Japan 30th Anniversary Ceremony
On 14 May 2026 W3C held its Japan Member Meeting with presentations reflected the latest developments and offered valuable insights into future W3C activities. Following that, it hosted the "W3C in Japan 30th Anniversary Reception" with W3C members and also many alumni who have established shape W3C in Japan over the years.
25 May 2026 12:42pm GMT
21 May 2026
W3C - Blog
W3C recognized on the 2026 Forbes Accessibility 200 list
The World Wide Web Consortium (W3C) is honored to be included in the Forbes Accessibility 200 list for 2026 in recognition of the impact that our Web Accessibility Initiative (WAI) has had on the world.
21 May 2026 12:49pm GMT
30 Apr 2026
W3C - Blog
Age-restrictions on the web and user privacy and safety
In this blog post, W3C CEO Seth Dobbs shares his thoughts about age-restrictions and user privacy on the web - a topic that was at the heart of the October W3C/IAB workshop on Age-Based Restrictions on Content, and recent W3C Members conversations.
30 Apr 2026 8:04pm GMT
18 Jan 2026
Official jQuery Blog
jQuery 4.0.0
On January 14, 2006, John Resig introduced a JavaScript library called jQuery at BarCamp in New York City. Now, 20 years later, the jQuery team is happy to announce the final release of jQuery 4.0.0. After a long development cycle and several pre-releases, jQuery 4.0.0 brings many improvements and modernizations. It is the first major … Continue reading
18 Jan 2026 12:29am GMT
11 Aug 2025
Official jQuery Blog
jQuery 4.0.0 Release Candidate 1
It's here! Almost. jQuery 4.0.0-rc.1 is now available. It's our way of saying, "we think this is ready; now poke it with many sticks". If nothing is found that requires a second release candidate, jQuery 4.0.0 final will follow. Please try out this release and let us know if you encounter any issues. A 4.0 … Continue reading
11 Aug 2025 5:35pm GMT
17 Jul 2024
Official jQuery Blog
Second Beta of jQuery 4.0.0
Last February, we released the first beta of jQuery 4.0.0. We're now ready to release a second, and we expect a release candidate to come soon™. This release comes with a major rewrite to jQuery's testing infrastructure, which removed all deprecated or under-supported dependencies. But the main change that warranted a second beta was a … Continue reading
17 Jul 2024 2:03pm GMT
29 May 2023
Smiley Cat: Christian Watson's Web Design Blog
7 Types of Article Headlines: Craft the Perfect Title Every Time
When it comes to crafting an article, the headline is crucial for grabbing the reader's attention and enticing them to read further. In this post, I'll explore the 7 types of article headlines and provide examples for each using the subjects of product management, user experience design, and search engine optimization. 1. The Know-it-All The […]
The post 7 Types of Article Headlines: Craft the Perfect Title Every Time first appeared on Smiley Cat.
29 May 2023 10:20pm GMT
09 Apr 2023
Smiley Cat: Christian Watson's Web Design Blog
5 Product Management Myths You Need to Stop Believing
Product management is one of the most exciting and rewarding careers in the tech world. But it's also one of the most misunderstood and misrepresented. There are many myths and misconceptions that cloud the reality of what product managers do, how they do it, and what skills they need to succeed. In this blog post, […]
The post 5 Product Management Myths You Need to Stop Believing first appeared on Smiley Cat.
09 Apr 2023 5:28pm GMT
11 Dec 2022
Smiley Cat: Christian Watson's Web Design Blog
The Key Strengths of the Best Product Managers
The role of a product manager is crucial to the success of any product. They are responsible for managing the entire product life cycle, from conceptualization to launch and beyond. A product manager must possess a unique blend of skills and qualities to be effective in their role. Strong strategic thinking A product manager must […]
The post The Key Strengths of the Best Product Managers first appeared on Smiley Cat.
11 Dec 2022 4:43pm GMT
01 Apr 2004
Planet PHP
ezSystems are classy folks

Last week I helped the folks at ezSystems debug some APC problems they were having. The problems ended up being a 64bit architecture problem (they have uber-fast Opterons) and the bug is now fixed in 2.0.3.
Today I received Python & XML from them (off my Amazon wishlist). Thanks guys!
On a side note, my wishlist seems borked. The list I get when I search on my email address or name is not the same one I can edit when I log into the site.
01 Apr 2004 6:53pm GMT
PHP april fools...
1st of April 2004 get's to it's end and I guess it's time, to summarize the recent April fools a bit. Not that I think anyone in the world believes in them, but some were quite funny:
1. Changes to case sensitivity in PHP.
Alan Knowles announced that PHP will change to the studlyCase API and therefor will get everything broken by changing established functions.
2. IBM takes over Zend.
Myself hacked a little article about IBM taking over Zend to make PHP a compete of Java.
3. The first PHP virus has been seen.
Wasn't there one last year, too?
4. PHP has been overtaken by Micro$oft.
Mhhh... a little bit unreliable, if they had been taken over by IBM this morning... Maybe one should first look, what others wrote...
5. And finally, PHP4 and 5 showed their real faces...
Take a look at a phpinfo() output!
I guess I missed some, so feel free to comment on this entry, if you found another!
01 Apr 2004 5:49pm GMT
PHP Virus Attacking Web Hosts
Symantec have a report of the virus here. I've yet to see any of the PHP news sites picking up on it but, using a virtual host account, managed to deliberately expose some PHP scripts to it. From examining the infected scripts, what's disturbing is once infected, every tim...
01 Apr 2004 12:19pm GMT

