Third party Argument 1 passed to XF\Template\Templater::setGroupStyles() must be of the type array

Affected version
2.0.1

Nirjonadda

Well-known member
#1
Server error log.

Code:
TypeError: Argument 1 passed to XF\Template\Templater::setGroupStyles() must be of the type array, boolean given, called in /home/nadda/public_html/src/XF/App.php on line 1451 src/XF/Template/Templater.php:406

Generated by: Arman Piash Dec 20, 2017 at 1:48 PM

Stack trace

#0 src/XF/App.php(1451): XF\Template\Templater->setGroupStyles(false)
#1 src/XF/App.php(1079): XF\App->setupTemplaterObject(Object(XF\Container), 'ThemeHouse\\Reac...')
#2 src/XF/Container.php(28): XF\App->XF\{closure}(Object(XF\Container))
#3 src/XF/App.php(2641): XF\Container->offsetGet('templater')
#4 src/XF/Pub/App.php(348): XF\App->templater()
#5 src/XF/Mvc/Dispatcher.php(280): XF\Pub\App->preRender(Object(XF\Mvc\Reply\View), 'raw')
#6 src/XF/Mvc/Dispatcher.php(44): XF\Mvc\Dispatcher->render(Object(XF\Mvc\Reply\View), 'raw')
#7 src/XF/App.php(1880): XF\Mvc\Dispatcher->run()
#8 src/XF.php(328): XF\App->run()
#9 index.php(13): XF::runApp('XF\\Pub\\App')
#10 {main}

Request state

array(4) {
  ["url"] => string(23) "/attachments/z-jpg.630/"
  ["referrer"] => string(42) "/threads/105668/"
  ["_GET"] => array(0) {
  }
  ["_POST"] => array(0) {
  }
}
 

Mike

XenForo developer
Staff member
#2
Are you using a cache object?

You seem to be having various errors that indicate unexpected data is being returned. You also seem to be having a number of errors that are specific to you, along with a history of errors caused by server issues dating back to XF1. It is very possible that these issues are intertwined and that you're actually having failed calls to your cache layer.
 

Mike

XenForo developer
Staff member
#4
but I can confirm that we are using Redis cache in config.php
Well that's a cache and it is the cause. It's triggering when cache actions are failing.

Are you using the out of the box Redis cache support or an add-on? If it's the latter, this might be something to check with the add-on author.
 

Nirjonadda

Well-known member
#5
Are you using the out of the box Redis cache support or an add-on?
No add-on, only using in /src/config.php

Code:
$config['cache']['enabled'] = true;
$config['cache']['provider'] = 'Redis';
$config['cache']['config'] = [
    'host' => '127.0.0.1',
];
 

Kier

XenForo Developer
Staff member
#6
It sounds like there is corrupt data in your cache - have you tried doing a drastic FLUSHALL on the Redis cache to see if it resolves the issue when there is fresh data?
 

Nirjonadda

Well-known member
#7
It sounds like there is corrupt data in your cache - have you tried doing a drastic FLUSHALL on the Redis cache to see if it resolves the issue when there is fresh data?
Yes, Now i am removed all the keys of all the existing database. I will wait for new error log from cache.

Code:
[root@ra ~]# redis-cli FLUSHALL
OK
[root@ra ~]#
 

Kier

XenForo Developer
Staff member
#8
Okay, let us know if the error(s) reappear - I think this may well explain all of your open bug reports.
 

Xon

Well-known member
#9
@Nirjonadda are you using the latest versions of phpredis (the php extension required for the built-in redis connector) and redis?

You should be getting exceptions on failed cache updates for redis to store dodgy data, otherwise all I can think of is memory corruption issue somewhere.

Have you tried doing a memory test? It might be your site has dodgy hardware somewhere.
 

Nirjonadda

Well-known member
#10
@Nirjonadda are you using the latest versions of phpredis (the php extension required for the built-in redis connector) and redis?

You should be getting exceptions on failed cache updates for redis to store dodgy data, otherwise all I can think of is memory corruption issue somewhere.

Have you tried doing a memory test? It might be your site has dodgy hardware somewhere.
phpredis version latest 3.1.5 and redis server version 3.2.2. How to check memory test?
 

lantek

Active member
#13
I've just been testing REDIS with the inbuilt XF2 support and I am seeing the same types of errors. Did you make any progress?
 

Steffen

Active member
#15
I'm getting similar errors that indicate that sometimes false is returned from the cache (instead of null).

XenForo uses the Doctrine RedisCache to store serialized PHP values in Redis. I think there is a race condition in this library: https://github.com/doctrine/cache/blob/master/lib/Doctrine/Common/Cache/RedisCache.php#L60

RedisCache calls "mget" to fetch multiple values. If one of these values is returned as false then it double-checks whether the value really doesn't exist by calling the "exists" method on the key. Now, if the value has just been (re-)created between the "mget" and the "exists" call then it thinks that false is the value of the specified key (although it isn't).

This is a conceptional issue of letting PhpRedis serialize the data (instead of doing that in the RedisCache library). With serialization enabled, PhpRedis returns false for a) keys that don't exist and b) for keys that exist and have the value false. To distinguish between these two cases, RedisCache uses the "exists" call which unfortunately introduces the described race condition.

Is false a legitimate cache value in XenForo? If not then the "exists" call could just be removed. The other alternative would be to modify RedisCache such that it does the serialization on its own.

Code:
TypeError: Argument 1 passed to XF\SimpleCache::__construct() must be of the type array, boolean given, called in src/XF/App.php on line 549 src/XF/SimpleCache.php:12

Stack trace
#0 src/XF/App.php(549): XF\SimpleCache->__construct(false)
#1 src/XF/Container.php(28): XF\App->XF\{closure}(Object(XF\Container))
#2 src/XF/App.php(2150): XF\Container->offsetGet('simpleCache')
#3 src/XF/App.php(1678): XF\App->simpleCache()
#4 src/XF/App.php(1601): XF\App->getGlobalTemplateData(Object(XF\Mvc\Reply\View))
#5 src/XF/Pub/App.php(350): XF\App->preRender(Object(XF\Mvc\Reply\View), 'json')
#6 src/XF/Mvc/Dispatcher.php(280): XF\Pub\App->preRender(Object(XF\Mvc\Reply\View), 'json')
#7 src/XF/Mvc/Dispatcher.php(44): XF\Mvc\Dispatcher->render(Object(XF\Mvc\Reply\View), 'json')
#8 src/XF/App.php(1945): XF\Mvc\Dispatcher->run()
#9 src/XF.php(328): XF\App->run()
#10 index.php(13): XF::runApp('XF\\Pub\\App')
#11 {main}
Code:
Uncaught TypeError: Argument 1 passed to XF\App::XF\{closure}() must be of the type array, boolean given, called in src/XF/App.php on line 1460 and defined in src/XF/App.php:555

Stack trace:
#0 src/XF/App.php(1460): XF\App->XF\{closure}(false, Object(XF\Container), 'options')
#1 src/XF/Container.php(28): XF\App->XF\{closure}(Object(XF\Container))
#2 src/XF/App.php(2158): XF\Container->offsetGet('options')
#3 src/XF.php(463): XF\App->options()
#4 src/XF/Entity/User.php(1614): XF::options()
#5 src/XF/Mvc/Entity/Manager.php(70): XF\Entity\User::getStructure(Object(XF\Mvc\Entity\Structure))
#6 src/XF/Repository/User.php(60): XF\Mvc\Entity\Manager->getEntityStructure('XF:User')
#7 src/XF/Repository/User.php(31): XF\Repository\User->getGuestUser()
#8 src/XF.php(367): XF\Repository\User->getVisitor(0)
#9 src/XF/Error.php(132): XF::visitor()
#10 src/XF/App.php(1956): XF\Error->logException(Object(ErrorException), false, '')
#11 src/XF.php(184): XF\App->logException(Object(ErrorException))
#12 [internal function]: XF::handleFatalError()
#13 {main}
  thrown in src/XF/App.php on line 555
 

Xon

Well-known member
#18
To be honest, this is something of a phpredis issue. Redis actually returns what is better considered "null" rather than "false". This isn't the first time phpredis has miss-handled return types. But changing it's behaviour is a massive backwards compatibility breaking change.
 
Last edited:

Steffen

Active member
#19
Yes, it is an issue with the built-in serialization feature of PhpRedis.

When using the built-in serialization, the underlying issue is that PhpRedis makes it impossible to distinguish between a non-existing value and the value false. When not using the built-in serialization, this issue does not exist because in this case get/mget either returns a string or false.

I therefore think that RedisCache should avoid using the built-in serialization feature of PhpRedis and do the serialization on its own. I agree that changing the behaviour of PhpRedis would be a massive headache. I'd therefore just not use the problematic parts of PhpRedis (the serialization feature).
 
Top