Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $12.00

Debugging in Drupal 8 is pretty sweet... if you know the tools to use.

Turning on Debugging

First, let's activate a debug mode so we can see errors... just in case some other developer makes a mistake and we have to debug it.

In sites/ there's an example.settings.local.php file that can be used to activate development settings locally. But first, we need to play with permissions: Drupal makes some files in this directory readonly for security. Start by making sites/default writable by us:

chmod 755 sites/default

Now, copy sites/example.settings.local.php to sites/default/settings.local.php:

cp sites/example.settings.local.php sites/default/settings.local.php

Finally, make sure we can write to settings.php:

chmod 644 sites/default/settings.php


On a production server, it's best to make sure these files are not writeable by whatever user runs your web server.

The settings.local.php file activates several things that are good for debugging, like a verbose error level. It also loads a file that we're going to talk about soon:

... lines 1 - 31
* Enable local development services.
$settings['container_yamls'][] = DRUPAL_ROOT . '/sites/';
* Show all error messages, with backtrace information.
* In case the error level could not be fetched from the database, as for
* example the database connection failed, we rely only on this value.
$config['system.logging']['error_level'] = 'verbose';
... lines 44 - 92

But just having settings.local.php isn't enough! Open settings.php. At the bottom, uncomment out the lines so that this file is loaded:

... lines 1 - 701
* Load local development override configuration, if available.
* Use settings.local.php to override variables on secondary (staging,
* development, etc) installations of this site. Typically used to disable
* caching, JavaScript/CSS compression, re-routing of outgoing emails, and
* other things that should not happen on development and testing sites.
* Keep this code block at the end of this file to take full effect.
if (file_exists(__DIR__ . '/settings.local.php')) {
include __DIR__ . '/settings.local.php';
... lines 715 - 727

Of course, we need to rebuild our cache and the Drupal Console in all its wisdom has a command for that:

drupal cache:rebuild

From this command you can clear all kinds of different caches, like the menu cache, render cache or leave it blank to do everything.

Side note: the Drupal Console app is built on top of the Symfony Console library, and you can take advantage of it to create really cool command line scripts like this if you want to. It's one of the best pieces of Symfony.

Back in the browser, if you refresh now, there's no difference: everything is roaring along. But, try deleting the roar() function and refresh. Now we get a nice error that says:

The controller for URI /the/dino/says/50 is not callable.

That's a way of saying "Yo! This route is pointing to a function that doesn't exist!" And when we put the function back and refresh, things are back to a roaring good time.

List all the Routes

Every page of the site - including the homepage and admin areas - has a route. And that leads me to the next natural question: what time is dinner? I mean, can I get a list of every single route in the system? Well, of course! And dinner is at 6.

Once again, go back to the trusty Drupal Console app. To list every route, run router:debug:

drupal router:debug

Wow! This prints every single route in the system, which is wonderful when you're trying to figure out what's going on in a project. This includes the admin route and our custom route.

To get more information about a route, copy it's internal name - that's the part on the left - and pass it as an argument to router:debug. This route has several curly brace routing wildcards that are passed to the getForm method of this controller class. This is pretty sweet, but we can go further!

Leave a comment!

  • 2020-07-07 Vladimir Sadicov

    Hey MonkeyBrain

    Thank you very much for you notes, it's very helpful! Unfortunately we can't update our course to be compatible with Drupal 9 right now but you notes can help many users so thank you again for sharing it!


  • 2020-07-06 MonkeyBrain

    As noted on previous chapters, if you are running this course on Drupal 9, at time of writing Drupal Console is not compatible with D9.
    And Drush does not give helpful debugging information for routes, unfortunately.
    Next best thing is to use the Devel module.
    composer require drupal/devel
    Then install the Devel module at admin/modules.
    Then clear cache and browse to devel/routes.
    You can see all the routes listed. If you press the 'Devel' button at the end of each row, you get all the extended debugging information for that route, but not nicely formatted like in Drupal Console, instead it looks like a var_dump of some kind.

  • 2017-07-12 Victor Bocharsky

    Hey alar ,

    Thanks a lot for sharing it! I think it could be useful for other users.


  • 2017-07-11 alar

    Of course I ran in to other issues later on. Don't mess with versions!!! Haha!

    It appears console broke -- with the error:

    Console is not installed at:____ You must execute the following composer commands: ____
    As per debug suggestions I had to remove:
    composer remove symfony/finder v3.3.4
    composer remove symfony/filesystem v3.3.4
    Then I could run:
    composer require drupal/console:~1.0 --prefer-dist --optimize-autoloader

    This still works:
    drupal router:debug views_ui.form_display

    Bottom line
    $ composer show | grep symfony/
    symfony/browser-kit v2.8.24 Symfony BrowserKit Component
    symfony/class-loader v2.8.24 Symfony ClassLoader Component
    symfony/config v2.8.24 Symfony Config Component
    symfony/console v2.8.24 Symfony Console Component
    symfony/css-selector v2.8.24 Symfony CssSelector Component
    symfony/debug v2.8.24 Symfony Debug Component
    symfony/dependency-injection v2.8.24 Symfony DependencyInjection Component
    symfony/dom-crawler v2.8.11 Symfony DomCrawler Component
    symfony/event-dispatcher v2.8.24 Symfony EventDispatcher Component
    symfony/expression-language v2.8.24 Symfony ExpressionLanguage Component
    symfony/filesystem v2.8.24 Symfony Filesystem Component
    symfony/finder v2.8.24 Symfony Finder Component
    symfony/http-foundation v2.8.24 Symfony HttpFoundation Component
    symfony/http-kernel v2.8.24 Symfony HttpKernel Component
    symfony/polyfill-apcu v1.4.0 Symfony polyfill backporting apcu_* functions to lower PHP versions
    symfony/polyfill-iconv v1.4.0 Symfony polyfill for the Iconv extension
    symfony/polyfill-mbstring v1.4.0 Symfony polyfill for the Mbstring extension
    symfony/polyfill-php54 v1.4.0 Symfony polyfill backporting some PHP 5.4+ features to lower PHP versions
    symfony/polyfill-php55 v1.4.0 Symfony polyfill backporting some PHP 5.5+ features to lower PHP versions
    symfony/process v2.8.24 Symfony Process Component
    symfony/psr-http-message-bridge v1.0.0 PSR HTTP message bridge
    symfony/routing v2.8.24 Symfony Routing Component
    symfony/serializer v2.8.24 Symfony Serializer Component
    symfony/translation v2.8.24 Symfony Translation Component
    symfony/validator v2.8.24 Symfony Validator Component
    symfony/var-dumper v3.3.4 Symfony mechanism for exploring and dumping PHP variables
    symfony/yaml v2.8.6 Symfony Yaml Component

  • 2017-07-11 alar

    The problem was:
    $ drupal router:debug views_ui.form_display
    PHP Fatal error: Call to undefined method Symfony\Component\Yaml\Inline::isHash() in public_html/d8-underthehood/vendor/symfony/yaml/Dumper.php on line 61
    PHP Stack trace:
    PHP 1. {main}() /usr/local/bin/drupal:0
    PHP 2. require() /usr/local/bin/drupal:10
    PHP 3. require() phar:///usr/local/bin/drupal/bin/drupal:3
    PHP 4. Symfony\Component\Console\Application->run($input = *uninitialized*, $output = *uninitialized*) phar:///usr/local/bin/drupal/bin/drupal.php:115
    PHP 5. Drupal\Console\Application->doRun($input = class Symfony\Component\Console\Input\ArgvInput { private $tokens = array (0 => 'router:debug',

    $ composer show | grep symfony/
    symfony/yaml v2.8.18 Symfony Yaml Component

    $php -v
    PHP 5.6.23

  • 2017-07-11 Victor Bocharsky

    Hey alar ,

    Thank you for sharing it! What was the problem if you don't mind to say? I wonder what version of symfony/yaml was installed before you downgrade to v2.8.6.


  • 2017-07-10 alar

    On Drupal 8.3.5. I ran into problems running drupal router:debug views_ui.form_display and ended up have to set back symfony/yaml to 2.8.6

    $composer -v require symfony/yaml:2.8.6

    Now it works!

    $ drupal router:debug views_ui.form_display
    Route views_ui.form_display
    Path /admin/structure/views/{js}/display/{view}/{display_id}/{type}
    _controller \Drupal\views_ui\Form\Ajax\Display::getForm
    compiler_class \Drupal\Core\Routing\RouteCompiler
    parameters view:
    tempstore: true
    type: 'entity:view'
    converter: drupal.proxy_original_service.paramconverter.views_ui

    _admin_route 1
    _route_filters method_filter

    _route_enhancers route_enhancer.param_conversion

    _access_checks access_check.entity

  • 2015-12-22 weaverryan

    Glad to hear it! I use bash and autocompletion (in general) works fine - I haven't hooked up the Drupal Console's auto-completion, however, but I imagine it would work fine (I use autocompletion for Symfony's console, which is accomplished in a similar way).

  • 2015-12-08 weaverryan

    I would try using DrupalConsole to enter debugging mode instead - For some reason, some people are having strange issues after entering debugging mode by including settings.local.php. But I haven't been able to repeat that yet :)

  • 2015-12-08 weaverryan

    Yea there is obviously some weirdness for some machines related to entering the debug mode. This is an excellent alternative (and really easier anyways).

  • 2015-12-02 Pietrino Atzeni

    If I comment out that line, drupal cache:rebuild complains about DRUPAL_ROOT not defined. I think this can be related to my PHP version (that's 5.5.29, on a MAC with El Capitan, installed with brew) but other than that, I don't know where else to dig...

  • 2015-12-02 Pietrino Atzeni

    Mine is 5.5.29.

  • 2015-12-02 Zachary Maximov


  • 2015-12-02 Darryl Norris

    You can enable debugging in D8 by running the command drupal site:mode dev with DrupalConsole.

  • 2015-12-02 Zachary Maximov

    Same problem. What is your PHP version?

  • 2015-12-01 weaverryan

    Hmm, I don't get this with a fresh 8.0.0. install (downloaded from This line *does* come from settings.local.php (you'll find mention of this class there), but the class itself is located in core/lib/Drupal/Component/Assertion/Handle.php and should be autoloaded just like everything else. So I'm not so sure about this. Does this information give you any clues?

  • 2015-12-01 Pietrino Atzeni

    Hi, I followed all the steps here, but when I uncomment the lines in settings.php, to include settings.local.php, I get a "Class 'Drupal\Component\Assertion\Handle' not found". I'm using drupal 8.0.0. Any suggestion?