Problem/Motivation
When enabling settings.local.php, the site throws an exception.
Steps to reproduce
- Run site install
- Load homepage
- Copy sites/example.settings.local.php to sites/default/settings.local.php
- uncomment
include __DIR__ . '/settings.local.php';
in settings.php - 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';
- Save the settings.local.php file
- 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.
Comments
Comment #1
dawehnerYou also have to copy sites/development.services.yml into sites/default.
Comment #2
BerdirYou don't have to actually copy that, but make sure you are using the latest example.settings.local.php, which automatically includes that file.
Comment #3
almaudoh CreditAttribution: almaudoh commentedThe way I did this in my case required 3 steps:
if (file_exists(DRUPAL_ROOT . '/sites/default/settings.local.php')) {
Comment #4
webchickThis 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:
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.
Comment #5
BerdirRe-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.
Comment #6
webchickMe neither. Where was the issue where this was discussed? It's probably worth pointing them back here.
Comment #7
Wim LeersMe 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:
Hence it got re-committed in #2315613: Add a development.services.yml for development. Posted at that issue to point people back here.
Comment #8
joelpittetWhat is the drawback to always loading the null backend?
Comment #9
BerdirIt means having two additional simple services that are not used during normal runtime.
Does not have an impact on performance.
Comment #10
Fabianx CreditAttribution: Fabianx commentedWhy 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.
Comment #11
damiankloip CreditAttribution: damiankloip commentedIt'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.
Comment #12
joelpittet@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).
Comment #13
damiankloip CreditAttribution: damiankloip commentedThat'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.
Comment #14
damiankloip CreditAttribution: damiankloip commentedThe 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.
Comment #15
Fabianx CreditAttribution: Fabianx commentedCan't we have a quick question in the installer to ask for production or development usage?
Comment #16
joelpittetI 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.
Comment #17
damiankloip CreditAttribution: damiankloip commentedOK, 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.
Comment #18
Wim LeersOnly if you're a developer. The "fast by default" is targeted at site builders (and novice developers).
In short: no, we can't, for technical reasons.
In detail: see the many issues/discussions about this :(
Exactly.
Also very true! :(
Have we already had discussions/ideas/issues on how to make this simpler?
Comment #19
Fabianx CreditAttribution: Fabianx commentedSO:
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.
Comment #20
webchickIf 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.
Comment #21
Fabianx CreditAttribution: Fabianx commentedI 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.
Comment #22
Fabianx CreditAttribution: Fabianx commentedAnyway:
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.
Comment #23
Fabianx CreditAttribution: Fabianx commentedIt 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.
Comment #24
Fabianx CreditAttribution: Fabianx commentedThe 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.
Comment #28
catchNot 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?
Comment #29
jhedstromFixing this by way of an installation toggle overlooks the usage of local settings when developing on a production site in a local environment.
Comment #30
Berdir#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).
Comment #31
BerdirAlso, 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.
Comment #32
jhedstromAh, good--that makes sense.
Comment #33
phpcoder2015 CreditAttribution: phpcoder2015 commentedMy 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)
Comment #34
gappleUpdated issue summary, including steps to reproduce
Comment #35
gappleWhen 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.
Comment #36
Fabianx CreditAttribution: Fabianx as a volunteer and at Tag1 Consulting commentedThere is definitely still a lot of actionable items around DX in here, so re-opening ...
Comment #37
cilefen CreditAttribution: cilefen commentedI tried the steps to reproduce from the issue summary on HEAD and could not reproduce the error.
Comment #38
gnugetNot 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.
Comment #39
cilefen CreditAttribution: cilefen commented@gnuget I followed the steps to reproduce on the latest 8.0.x HEAD and there is no error.
Comment #40
gnugetSorry you are right.
I just updated the steps to reproduce the problem.
Comment #41
gnugetComment #42
joelpittetThis is easy to reproduce. I wonder if we can rebuild the container if the
$settings['container_yamls']
is different from the dumped container?Comment #43
hass CreditAttribution: hass commentedThis is such a major WTF DX, can you get this issue resolved and into 8.0.2, please?!
Comment #44
dawehnerTheoretically we could do the following.
Comment #45
BerdirInteresting 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?
Comment #46
jlbellido#44 works for me. Thanks!
Comment #47
damiankloip CreditAttribution: damiankloip at Tag1 Consulting commentedThis works for me too, and I don't think we will have a better idea than this. Nice work!
Comment #48
dawehnerI would say so yes. Another md5 call though is also not the worst.
Comment #49
catchCommitted/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.
Comment #52
fortis CreditAttribution: fortis as a volunteer commented#44 works for me too
Comment #53
dmouse#44 works for me
Comment #55
johntang CreditAttribution: johntang commented"run /rebuild.php" works for me.
Comment #56
jptillman CreditAttribution: jptillman commentedI 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?
Comment #57
jptillman CreditAttribution: jptillman commentedComment #58
jptillman CreditAttribution: jptillman commentedComment #59
jenlamptonI'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?
Comment #60
phma CreditAttribution: phma at OM commentedI 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
After
drush cr
I could addComment #61
cosolom CreditAttribution: cosolom commentedSometimes this error can occur when missed services.yml (even if enabled development.services.yml)
Comment #62
irohit786 CreditAttribution: irohit786 as a volunteer commented#3 https://www.drupal.org/project/drupal/issues/2348219#comment-9202547 above, resolved my issue
Comment #63
ninobrownh20 CreditAttribution: ninobrownh20 commentedI 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.