Problem/Motivation

When enabling settings.local.php, the site throws an exception.

Steps to reproduce

  1. Run site install
  2. Load homepage
  3. Copy sites/example.settings.local.php to sites/default/settings.local.php
  4. uncomment include __DIR__ . '/settings.local.php'; in settings.php
  5. In the settings.local.php file uncomment any of the following options:
    • //$settings['cache']['bins']['render'] = 'cache.backend.null';
    • //$settings['cache']['bins']['dynamic_page_cache'] = 'cache.backend.null';
  6. Save the settings.local.php file
  7. Reload homepage

The dumped container does not have the service added via $settings['container_yamls'].
Rebuilding the container will resolve this problem.

Proposed resolution

TBD:

Document needing to rebuild the container (drush cr or /core/rebuild.php)
OR
Auto-rebuild the container if the $settings['container_yamls'] is different from the dumped one.

Remaining tasks

User interface changes

API changes

Data model changes

Original report by Kyna

Hello, from Beta1, when I load the settings.local.php file inside my site configuration, I have this error after cache clear :

Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException: You have requested a non-existent service "cache.backend.null". in Symfony\Component\DependencyInjection\Container->get() (line 303 of core/vendor/symfony/dependency-injection/Symfony/Component/DependencyInjection/Container.php).

I can't disable the cache rendering and it's a problem, I can't work on my theme.

Have you a solution please ? Thanks.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dawehner’s picture

You also have to copy sites/development.services.yml into sites/default.

Berdir’s picture

Category: Bug report » Support request
Priority: Critical » Normal
Status: Active » Fixed

You don't have to actually copy that, but make sure you are using the latest example.settings.local.php, which automatically includes that file.

almaudoh’s picture

The way I did this in my case required 3 steps:

  1. Copy example.settings.local.php in sites/ into sites/default/settings.local.php
  2. Copy default.services.yml in sites/default/ into sites/default/services.yml
  3. Uncomment the 3 lines at the bottom of sites/default/settings.php that starts from if (file_exists(DRUPAL_ROOT . '/sites/default/settings.local.php')) {
webchick’s picture

Category: Support request » Bug report
Priority: Normal » Major
Status: Fixed » Active
Issue tags: +DX (Developer Experience)
FileSize
141.75 KB

This is more than a support request. We have a pretty big DX issue here, IMO.

almaudoh's steps in #3 work *if* you do them *before* installing. So, at minimum, we need to add those steps to INSTALL.txt.

However, if you don't, and try to add the lines at run-time instead (which was a perfectly valid thing to do in Drupal 7), you end up with:

Twig runtime error cache.backend.null

The way to recover from this is to run /rebuild.php. But nothing in this error message tells you this, and because you're new to Drupal 8 you don't know rebuild.php exists yet.

Berdir’s picture

Re-install shouldn't be necessary, but a drush cr is yes.

I still don't understand why people want to remove the null and memory cache backends from the default core.services.yml so badly, we have hundreds of services in there, two simple ones really don't make a difference.

webchick’s picture

Me neither. Where was the issue where this was discussed? It's probably worth pointing them back here.

Wim Leers’s picture

Me neither… this was done in #2309575: [Revert] Remove the null and memory backend definitions from core.services.yml in favour of devel module providing them instead — I argued against it, precisely for this reason, but lost:

One downside of this patch is that you'll have to copy and rename *two* files instead of one. But it seems like everybody is okay with that, because it'll give us a cleaner container.

Hence it got re-committed in #2315613: Add a development.services.yml for development. Posted at that issue to point people back here.

joelpittet’s picture

What is the drawback to always loading the null backend?

Berdir’s picture

It means having two additional simple services that are not used during normal runtime.

Does not have an impact on performance.

Fabianx’s picture

Why do you need to copy that 2nd template?

Berdirs steps should be working and copying the local.php file should still work after installation.

So I think this is a plain bug, where we reference the wrong file.

damiankloip’s picture

It's not really a performance thing. That will be negligable. It's more an example thing, these services are useless for anything but development so they should not be in my production container. Simple.

The fact that we need to rebuild to get changes will be the case for anything involving the container. That's definitely not a reason to leave things in there. So, documentation maybe.

joelpittet’s picture

@damiankloip DX is the reason to leave the null backend service in. Sure documentation would help but won't alleviate the support requests. Watch @mortendk's video from Amsterdam and notice how he just repeatedly ran drush cr just to see his changes. I'd likely do the same thing until it frustrates me enough to read the documentation to find out why it's not working as I espect it should.

For an analogy, when you flip a light switch in your house(turn caching off) do you expect to read a manual(drupal docs) on how to wire up the fusebox(service container).

damiankloip’s picture

That's not really comparable IMO, and not a great example. You don't need to know anything about the internals of the container.

Morten running drush cr to see his changes could only be once for this problem.

damiankloip’s picture

The best solution really IMO is don't do all of this fast by default stuff.

The first thing you have to do in 99% of cases is turn it straight back off again.

Fabianx’s picture

Can't we have a quick question in the installer to ask for production or development usage?

joelpittet’s picture

I am just trying to get the point across that it's a big problem.

Seems like adding a null backend is a small, negligible consession for a dx win.

Could care less if caching is on or off by default. But we need to make turning it off as painless as possible.

Making a change and not seeing the results of that change is huge.

damiankloip’s picture

OK, fair enough. This is just one example of needing to rebuild the container though. This is why I think just adding this back does not really fixing the general problem, just this particular one.

Wim Leers’s picture

The first thing you have to do in 99% of cases is turn it straight back off again.

Only if you're a developer. The "fast by default" is targeted at site builders (and novice developers).

Can't we have a quick question in the installer to ask for production or development usage?

In short: no, we can't, for technical reasons.
In detail: see the many issues/discussions about this :(

Seems like adding a null backend is a small, negligible consession for a dx win.

Exactly.

This is just one example of needing to rebuild the container though. This is why I think just adding this back does not really fixing the general problem, just this particular one.

Also very true! :(
Have we already had discussions/ideas/issues on how to make this simpler?

Fabianx’s picture

SO:

Why exactly can't the attached patch technically not be implemented?

It works for me!

Screenshot:

Things to consider:

- The choosing to lax the check for the file copying being the same owner based on development flag to lax this needs security review.
- I wanted to collapse the fieldset, but that was not possible.

I still think this is a good compromise.

webchick’s picture

If we want to start adding options to the installer we're going to need UX team sign-off on this. I'm not in favour, however. The point of "fast by default" is that in order to make your site not-fast, you need to go around and start changing/disabling settings. And then, presumably, you will remember where those settings were and can turn them back to fast again when your site moves into production.

By making it an install-time toggle, a) you never learn where those settings are that you need to untoggle, b) the poor soul who takes the site you developed and goes live with it certainly won't know where those settings are, nor that this selection was chosen at install time, and their shiny new D8 site will be prohibitively slow.

Fabianx’s picture

I am still exploring options.

The previous patch was only copying the file, but not enabling it.

The now attached patch also enables it by default and ensures settings are before the settings.local.php and not after, which is useful on its own.

Possible ways:

- Remove the UI, but leave the $settings['development'], which makes it possible to vary the container on it - which means it will be automatically used and not-used.
- It also gives more insight and allows easier disabling for production, such less error prone.

Fabianx’s picture

Anyway:

Proven the point it is _technically_ possible and would allow automatic container rebuild, which is what this issue was overall about in the first place.

Maybe we can use some non-GUI parts of the patch still.

Fabianx’s picture

It turns out container variations baed on settings are possible easily.

We should probably split this patch up into different tasks, but there is two options:

- Always run a hash over all $settings - might need a method to exclude if we have any dynamic ones, but do not think we support that.
- Only run the hash over $settings if $settings['development'] == TRUE

Still changing any setting, will nicely create a new container on the storage and same as twig we wildcard delete, so no problem with garbage collection on drush cr.

Fabianx’s picture

Status: Active » Needs review

The previous patch can be split up in four parts:

a) Ensure container can be varied based on content of $settings - optionally only if $settings['development'] = TRUE

- This solves the container rebuild problem nicely.

b) Ensure the installer does not tuck all their stuff to the end, but to a defined magic comment point in the default.settings.php - if that exists.

- This removes a big WTF!, because settings.local.php should always be last as stated in the comment.

c) Move from out-commented setting for the settings.local.php to a $settings['development''] = TRUE / FALSE and having the if (file_exists) be active by default - only if that option is set.

- Better DX to do things, better ways to react in the system to when development mode is on.

d) UX changes to activate development by default - probably least likely to land and therefore very probably a: won't fix.

Was still fun exploring that option and making it technically possible.

Status: Needs review » Needs work

The last submitted patch, 23: you_have_requested_a-2348219-23.patch, failed testing.

catch’s picture

Not sure about a toggle, but how about setting it based on minimal vs. standard profile?

I think this is more an issue of settings vs. container getting out of sync than fast by default. What about #2331411: Replace $settings['cache'] with container parameters.? Wouldn't that fix it?

jhedstrom’s picture

Version: 8.0.0-beta1 » 8.0.x-dev

Fixing this by way of an installation toggle overlooks the usage of local settings when developing on a production site in a local environment.

Berdir’s picture

#2429321: Verify that the configured service exists before calling it in CacheFactory should at least make the exception go away, but then it will silently not work, which is also not perfect, but I'm not sure something between is easily possible. Moving the configuration to container parameters would have the same problem (not working until you do a cache clear).

Berdir’s picture

Also, note that there's no issue with copying a production site to a local installation, this is about a mismatch between settings.php and the dumped container, you won't copy that from production.

jhedstrom’s picture

Also, note that there's no issue with copying a production site to a local installation, this is about a mismatch between settings.php and the dumped container, you won't copy that from production.

Ah, good--that makes sense.

phpcoder2015’s picture

My friends. Is there a fix for this yet? It's so annoying to go to Performance -> Clear cache all the time just to see how new CSS style in the menu looks which is placed inside "sidebar first" works. (i'm using drupal-8.0.0-beta9)

gapple’s picture

Issue summary: View changes

Updated issue summary, including steps to reproduce

gapple’s picture

Category: Bug report » Support request
Priority: Major » Normal
Status: Needs work » Closed (cannot reproduce)
Issue tags: +Triaged at DrupalCon Los Angeles 2015

When running site-install with settings.local.php already enabled, no errors occur.

When enabling settings.local.php after site install is complete, the exception message is preceded by a message to run rebuild.php, which should be sufficient for a user newer to Drupal to understand the next step required to resolve the error.

Fabianx’s picture

Category: Support request » Bug report
Priority: Normal » Major
Status: Closed (cannot reproduce) » Active
Issue tags: -Triaged at DrupalCon Los Angeles 2015

There is definitely still a lot of actionable items around DX in here, so re-opening ...

cilefen’s picture

I tried the steps to reproduce from the issue summary on HEAD and could not reproduce the error.

gnuget’s picture

Not sure why you couldn't reproduce the error, but I just do it with the summary steps. So I'm not sure if this really needs an update.

cilefen’s picture

@gnuget I followed the steps to reproduce on the latest 8.0.x HEAD and there is no error.

gnuget’s picture

Issue summary: View changes

Sorry you are right.

I just updated the steps to reproduce the problem.

gnuget’s picture

joelpittet’s picture

Issue summary: View changes

This is easy to reproduce. I wonder if we can rebuild the container if the $settings['container_yamls'] is different from the dumped container?

hass’s picture

This is such a major WTF DX, can you get this issue resolved and into 8.0.2, please?!

dawehner’s picture

Status: Active » Needs review
FileSize
744 bytes

Theoretically we could do the following.

Berdir’s picture

Interesting idea!

Works for me, just wondering if we should shorten that a bit? The database backend does it automatically, so I guess we can also rely on that?

jlbellido’s picture

#44 works for me. Thanks!

damiankloip’s picture

Status: Needs review » Reviewed & tested by the community

This works for me too, and I don't think we will have a better idea than this. Nice work!

dawehner’s picture

The database backend does it automatically, so I guess we can also rely on that?

I would say so yes. Another md5 call though is also not the worst.

catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed/pushed to 8.1.x and cherry-picked to 8.0.x. Thanks!

Added commit credit to everyone with 3+ comments on this issue since this took a while to figure out.

  • catch committed 61fb21e on 8.1.x
    Issue #2348219 by Fabianx, dawehner, webchick, Berdir, damiankloip,...

  • catch committed ce08386 on 8.0.x
    Issue #2348219 by Fabianx, dawehner, webchick, Berdir, damiankloip,...
fortis’s picture

#44 works for me too

dmouse’s picture

#44 works for me

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

johntang’s picture

"run /rebuild.php" works for me.

jptillman’s picture

I installed Drupal 8.7.8 minimal profile and followed the steps referenced early in this issue to enable the settings.local.php and services.yml and uncommented the render and dynamic_page_cache lines to set them to cache.backend.null. Reloading the site showed the non-existent service message in plain text, with escaped HTML (perhaps because I'm using a minimal theme).

Problem is, calling /rebuild.php as recommended in this issue thread *results in the same error message* and does not fix anything. If I re-comment the settings lines, things work again. It appears that I'm completely unable to use the null backend cache at this point.

Any suggestions? Has something changed since this issue was closed?

jptillman’s picture

Version: 8.0.x-dev » 8.7.8
jptillman’s picture

Version: 8.7.8 » 8.0.x-dev
jenlampton’s picture

I'm having the same problem as #56.

Working on a Drupal 9 site today (same site I've been working on for a few months) and I hit the fatal Fatal error: Uncaught Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException: You have requested a non-existent service "cache.backend.null".

I double checked and my site is already doing all the things recommended in this post. Doing a drush cr results in the same error.

@jptillman do you remember what your solution was?

phma’s picture

I just ran into the same issue. This helped me solve it:
https://www.drupal.org/forum/support/post-installation/2015-10-31/disabl...

I added these lines to my services.local.yml

parameters:
  http.response.debug_cacheability_headers: true
services:
  cache.backend.null:
    class: Drupal\Core\Cache\NullBackendFactory

After drush cr I could add

$settings['cache']['bins']['render'] = 'cache.backend.null';
$settings['cache']['bins']['dynamic_page_cache'] = 'cache.backend.null';
cosolom’s picture

Sometimes this error can occur when missed services.yml (even if enabled development.services.yml)

irohit786’s picture

ninobrownh20’s picture

I had this problem on Drupal 9 and it was due to local development services not being loaded in my settings.local.php, adding the following resolved the error.

/**
 * Enable local development services.
 */
$settings['container_yamls'][] = DRUPAL_ROOT . '/sites/development.services.yml';