0

Out of nowhere without any changes to the view or the views data I suddenly started receiving this error:

Warning: Invalid argument supplied for foreach() in views_handler_filter->prepare_filter_select_options() (line 1104 of /var/www/site/public_html/profiles/commerce_kickstart/modules/contrib/views/handlers/views_handler_filter.inc).

Warning: Invalid argument supplied for foreach() in _form_options_flatten() (line 2684 of /var/www/site/public_html/includes/form.inc).
An illegal choice has been detected. Please contact the site administrator.

Warning: Invalid argument supplied for foreach() in form_select_options() (line 2836 of /var/www/site/public_html/includes/form.inc).

The view has an exposed filter and the view is unusable until cache is cleared, then after some time it "blows up" again.

Prior to this starting happening I created a custom module page which creates a JSON structure with db queries and caches it. Can this be a caching issue or can cache run out?

Edit:

I have services nodes, and those services nodes have a taxonomy reference field_service_locations. The view that breaks displays the nodes and has an exposed filter for choosing the service location (based on the same field_service_locations)

In the log I see another error message happening right before this:

Illegal choice 12 in field_service_locations element.

This error is from one of the services page, however the term with id 12 is a location term, and exists.

However the select list displays no values and also when editing the views filter, it doesn't have values until cache clear.

Further down the road

I have been trying to pinpoint the issue further, what makes it more difficult is that I don't know exactly how to replicate it, as it just happens after a period of time.

I have pinpointed the cache to clear, that resolves the issue is "class registry" or "page and else" - not sure yet what to do with this information.

With the help from Shawn Conn I've been able to further pinpoint the issue that the $options variable received by prepare_filter_select_options() is FALSE instead of an array.

I'm not sure if my custom module that caches data could be the culprit (testing it will take some time as I'll have no other option than to disable the module caching part and wait to see if the issue rises again or not), it's however implemented as follows:

function custom_module_json_output_menu()
{
    $items = array();
    $items['services/%/json'] = array(
        'access callback'   => true, // available to all
        'page callback'     => '_services_json_object', // defined below
        'page arguments'    => array(1),
        'delivery callback' => 'drupal_json_output'
    );

    return $items;
}

function _services_json_object($service_type) {

    $cache_id = "services_json_".$service_type;
    $response = cache_get($cache_id, 'cache');
    if (empty($response)) {
        $response = array();

        $service = taxonomy_term_load($service_type);
        if ($service->vocabulary_machine_name == 'product_category') {
            // populate $response...
        }
        cache_set($cache_id, $response, 'cache', CACHE_PERMANENT);
    }

    return $response;
}

I also deleted rows from the cache_bootstrap tableone-bu-one, none seemed to resolve the issue and truncating the table completely didn't resolve either. As pointed out to me, that the common table for both cache clears that seem to resolve the issue is this table I'm in the ditch again. My site does have 2 languages, and I just noticed that while on the english version this seems to hit the fence, the german one is ok.

EDIT 3:

Disabling the caching on my custom module does not seem to be the issue, as the error happened again.

Problem still unsolved and I'm out of places to debug in the database. What could possibly cause a views select options exposed filter to suddenly no longer have options..? It's not the cron, and this happens even overnight when there's no activity (all this is in a dev only accessible environment)

EDIT 4:

I seem to be able to reproduce this by runing cron a couple of times, not sure what that means.

Yes, it's definately cron, and after running cron I get no errors. Even though clearing class registry through the admin menu "flush cache -> class registry" works, invoking registry_update() does not resolve the issue. Neither does registry_rebuild() which seems to be the function "class registry" clear invokes, which in turn invokes registry_update() and system_rebuild_module_data(). Or is calling any of those fron drush ev not supposed to work?

As it seems to me, the class registry clear also invokes clear all cashe, as there's no break after the cache. This may be why "drush cc all" also seems to resolve the problem, so I'm afraid I just got further from the cause of this issue.

cache_clear_all('*', 'cache_views', TRUE) seemed to be the one that solves the issue, and makes running cron no longer cause the issue. However flushing all caches, makes cron cause the issue again.

Again, this error is resolved with cache clear, but only cache clear. This view is my front page view :(

2
  • Is there any broken handler there in views configuration?
    – Cool
    Commented Jun 15, 2016 at 8:55
  • the views configuration page doesn't display any errors, and all the handlers are the default ones, haven't made any modifications. Which makes this situation so confusing is, that the error isn't there at all times, over some time period it appears and will not be resolved until class registry clean or the "page and else" cache clear. Then it'll work perfectly until the next time it gets messed up, and I don't have any ways to trace when and what is causing this change and what the change is.. Commented Jun 15, 2016 at 9:40

1 Answer 1

3
+50

A few key things to know will help debugging here.

The errors mentioned seem to be symptoms of your view's exposed filter form selectbox not being correctly built. As the views_handler_filter::prepare_filter_select_options() method name implies, this function is responsible for building your selectbox options. For some reason, the $options data supplied to it is empty. The "illegal choice" errors are where the exposed filter form being submitted with a value that's not in the empty selectbox.

As you've identified, there is bad data in your cache. It helps to know that the Admin menu empty cache options you've selected affects a few Drupal cache tables. For Class registry, you're touching (via _registry_update()) registry, registry_file, & cache_bootstrap (the lookup_cache entry) tables. In Page and else, you're touching the cache, cache_bootstrap, cache_filter, & cache_page tables.

Given that cache_bootstrap is the common entry here, you might want to inspect that. If your custom module is affecting this table (doesn't seem likely but there could be some odd bug), that might be relevant. More relevant might be the cache_bootstrap.lookup_cache entry that is both touched in both cache flush operations. It contains class name/include file entries. If this is corrupted, perhaps a key include/class isn't being included that's key to making your selectbox options appear.

With this information known, you have to identity the relationship between the bad cache data, what cache entry is causing problems, and how it relates to your rendered select options.

For troubleshooting, a ddebug_backtrace() placed in the prepare_filter_select_options() will produce a stack trace that might give you indication why no data is being supplied to the method and trace it back to a bad cache lookup.

For recreating, it might be useful to backup your site once the cache data is corrupted. One strategy you might try to employ is to selectively remove cache entries until you find the one corrupted entry that is causing the problem. Since you have a snapshot of the site DB, you can restore it as much as needed to narrow down the possible source of the bad cache data.

Once you've identified the cache entry in question and how it relates to prepare_filter_select_options(), hopefully that should shed some light on how/why things are misbehaving.

7
  • Wow, I'm impressed, that is very detailed and helpful! Got a lot of new knowledge. I've been able to track down that the the $options variable used in prepare_filter_select_options() which is expected to be an array is FALSE instead. but the functions that actually build the form don't show data in the debug but instead say "recursion". Could this be at all caused by a custom cahing module I made? Will update the question with the code Commented Jun 13, 2016 at 9:11
  • It doesn't seem likely to me unless your caching might step on the same entries that prepare_filter_select_options() depends on. A simple way to test that is to just disable your custom module to see if the problem goes away. As far the "recursion" entry, I believe that occurs when you have recursive references ( ddebug_backtrace() has a mechanism to prevent it printing out an infinite chain of references). Also note, prepare_filter_select_options() is a recursive function; it descends through the array for options that are grouped.
    – Shawn Conn
    Commented Jun 13, 2016 at 18:47
  • Thanks for the response, in my original question edit I already determined that my custom module does not affect this at all. However I also determined that truncating any of the tables manually didn't do anything either (I accidentally also truncated the registry tables and learned a lesson there, got to manually restore the tables from a backup) Commented Jun 13, 2016 at 18:52
  • Yeah. This is a tricky bug hunt. You need to find cache/filter options relationship, then find what could be impact the cache. Good luck on the hunt.
    – Shawn Conn
    Commented Jun 13, 2016 at 19:02
  • I still haven't resolved the issue, out of ideas, but I awarded the bounty, so it wouldn't go completely missing in the void.. Commented Jun 20, 2016 at 6:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.