When working on a Drupal 8 website in my local environment, I'm getting the following warning on each page:

Error messageWarning: assert(): At least one placeholder strategy must be present; by default the fallback strategy \Drupal\Core\Render\Placeholder\SingleFlushStrategy is always present.: "!empty($this->placeholderStrategies)" failed in Drupal\Core\Render\Placeholder\ChainedPlaceholderStrategy->processPlaceholders() (line 43 of core/lib/Drupal/Core/Render/Placeholder/ChainedPlaceholderStrategy.php).

The assertion in question is:

// Assert that there is at least one strategy.
    assert('!empty($this->placeholderStrategies)', 'At least one placeholder strategy must be present; by default the fallback strategy \Drupal\Core\Render\Placeholder\SingleFlushStrategy is always present.');

This assertion should not be failing, since the SingleFlushStrategy is actually present in the placeholderStrategies array. I'm guessing that the problem is that when assert executes the contents of the assertion string, it is outside of the context of the ChainedPlaceholderStrategy class, and therefore it doesn't have access to the protected $placeholderStrategies property.

A simple solution should be to remove the quotes, so empty() is called in the context of the class function where it has access to the protected variable and can evaluate it properly.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

mikemccaffrey created an issue. See original summary.

jhedstrom’s picture

Could you include the stack trace that triggers this? (I think if xdebug is enabled it will print with the warning.)

The reason the assert is in quotes is so it doesn't execute any code in a production environment.

Wim Leers’s picture

Agreed, STR would be great. #2's analysis is spot-on.

Very curious how you're triggering this :D I can't reproduce for sure.

dawehner’s picture

Yeah, $protected is not a problem in asserts, see https://3v4l.org/WDoHQ

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

fgm’s picture

Version: 8.3.x-dev » 8.2.x-dev

Just got it on today's 8.2.x

* Drupal version 6448749
* NO contrib (not even devel/kint)
* MacOS X
* php -v

PHP 7.1.0beta1 (cli) (built: Jul 29 2016 07:50:40) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.1.0-dev, Copyright (c) 1998-2016 Zend Technologies
with Zend OPcache v7.1.0beta1, Copyright (c) 1999-2016, by Zend Technologies

Page worked a moment ago on PHP 7.0. Upgraded to 7.1 and got this. Drush command work normally. Drush cr does not fix it.

The problem disappears when reverting to 7.0.

nketchum’s picture

Confirming #6, php 7.1 gives me assertion failures on drush and page loads.

fgm’s picture

It seems the example linked to by dawehner actually shows that HHVM and PHP7.1 differ from PHP5.x and 7.0 on that example, which could explain this observation:

- Older versions fail the assert()
- Newer ones succeed it.

Could be related to the "expectations" change for assert() in 7.1: http://php.net/manual/fr/function.assert.php#function.assert.expectations.

With 7.1, if zend.assertions is 0 or -1, the bug does not trigger. If zend.assertions is 1, it appears, whether assert.options is 0 or 1.

fgm’s picture

As mentioned in the issue summary, the problem goes away if the assertion is not quoted: since assert() is a language construct in PHP 7.1 (and possible HHVM), the assertion is not evaluated anyway.

Pending further investigation, the somewhat dubious patch attached addresses the issue for now. Let's run the bot (but it doesn't have 7.1 anyway).

Just hoping this won't mean revisiting #2408013: Adding Assertions to Drupal - Test Tools. and #2492225.

fgm’s picture

Just checked and the problem is also present in 8.1.x HEAD, as expected.

mikemccaffrey’s picture

Sorry for the delay. Here is the stacktrace I get with the error message:

Drupal\Core\Render\Placeholder\ChainedPlaceholderStrategy->processPlaceholders(Array) (Line: 56)
Drupal\Core\EventSubscriber\HtmlResponsePlaceholderStrategySubscriber->onRespond(Object, 'kernel.response', Object) (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.response', Object) (Line: 184)
Symfony\Component\HttpKernel\HttpKernel->filterResponse(Object, Object, 1) (Line: 166)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 64)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 206)
Drupal\page_cache\StackMiddleware\PageCache->fetch(Object, 1, 1) (Line: 120)
Drupal\page_cache\StackMiddleware\PageCache->lookup(Object, 1, 1) (Line: 74)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 50)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 628)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

Does this help at all?

fgm’s picture

Do you still have the issue when applying the patch I suggested ?

danielnolde’s picture

Not sure whether this PHP-Version-dependent condition is the right approach to fix the cause, but patch in #9 seems to fix the warning (at least in my instance).

Thanks, @fgm !

fgm’s picture

Judging from the PHP 7.2 deprecation RFC, we could just as well start removing our "assert(string)" optimizations for 8.3.0

https://wiki.php.net/rfc/deprecations_php_7_2

Wim Leers’s picture

See this Twitter conversation with Nikita Popov, who proposed that RFC: https://twitter.com/nikita_ppv/status/800800944804036608.

(@fgm triggered it, so he's aware of it. But I think anybody following this issue and looking at #14 should be aware of it.)

cilefen’s picture

phileas75’s picture

patch #9 work for me. Thx.

cilefen’s picture

Issue tags: +PHP 7.1

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

mr.baileys’s picture

Ran into the same issue while running some tests with PHP 7.1.0RC3. After upgrading to PHP 7.1.1, the assertion no longer fails.

Might be caused by/related to Bug #73303 - Scope not inherited by eval in assert() (if that's the case, I assume this issue can be closed?)

klausi’s picture

Aki Tendo’s picture

The issue definately needs revisiting. PHP 7 lets us turn assertions off entirely, PHP 5 forces us to use a now deprecated approach unless we want a slow down. Perhaps the following approach would be best, though it is nuanced.

For trivial operations, like this particular one, just don't use the eval method. The code becomes:

<?php
assert(!empty($this->placeholderStrategies), '...');

BTW, why are we merely asserting !empty here? Can't we assert the interface?

<?php
assert($this->placeholderStrategies instanceof PlaceholderStrategyInterface );

Anyway, in the event that we have an assertion that is time consuming to execute, we put it in an assertion method in the same class and guard against accidental execution in that function like so

<?php
public function foo() {
  assert($this->assertValidStartStateOfFoo(), '');
}

private function assertValidStartStateOfFoo() {
  if (assert_options(ASSERT_ACTIVE) == 0) {
    return TRUE;
  }
  // rest of test here
}

This isn't idea, but better than the alternative for PHP 5. I don't know if PHP 7 can be put into the nonsensical state of zend.assertions = 1 and assert.active = 0 -- that's something to be alert for if this solution is used.

EDIT: It can for BC reasons.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

andypost’s picture

Version: 8.6.x-dev » 8.7.x-dev

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

needs-review-queue-bot’s picture

Status: Needs review » Needs work
FileSize
179 bytes

The Needs Review Queue Bot tested this issue. It either no longer applies to Drupal core, or fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

Apart from a re-roll or rebase, this issue may need more work to address feedback in the issue or MR comments. To progress an issue, incorporate this feedback as part of the process of updating the issue. This helps other contributors to know what is outstanding.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.