Ok, it turns out that the default value for the session_stale field in the user table is NULL. Until permissions get flushed this value will remain NULL. Once permissions are flushed, it will contain a serialized array something like a:1:{i:1;s:3:"web";}
Since array_search requires an array to search, that initial NULL value is invalid.
To at least temporarily stop the constant errors, I made a small addition to the moduser.class.php file, adding a conditional before the array_search block:
$staleContexts = $this->get('session_stale');
if($staleContexts) {
$stale = array_search($context, $staleContexts);
if ($stale !== false) {
$reload = true;
$staleContexts = array_diff($staleContexts, array($context));
$this->set('session_stale', $staleContexts);
$this->save();
}
}
}
I don't think this will have any effect other than to skip the whole thing if it's NULL or otherwise empty, but given the convoluted nature of this whole can of worms I wouldn't want to bet on it. It would probably be better to make a plugin to flush permissions after the user is saved, at least until a more permanent fix is done.