drush updb fails when upgrading to 1.11.0 on Drupal 11.3 because entityqueue_post_update_relationship_limit_queue_list (introduced in #2746067) triggers a schema validation error via ConfigEntityUpdater.
Steps to reproduce:
- Have a Drupal 11.3.x site with entityqueue installed.
- Have at least one View with an entityqueue relationship filter that has a
limit_queuevalue set. - Update entityqueue from 1.10.x to 1.11.0.
- Run
drush updb.
Expected result: Database updates run successfully.
Actual result:
[error] entityqueue_post_update_relationship_limit_queue_list threw an exception: Drupal\Core\Config\Schema\SchemaIncompleteVaultException: The configuration property display.default.display_options.filters.entity_queue_in_queue.options.limit_queue has an invalid value (invalid type).
Root cause: The post-update hook uses ConfigEntityUpdater, which internally calls $view->save(). On Drupal 11.3, ConfigSchemaChecker fires on every entity save. The hook writes an associative array (e.g. ['api_docs' => 'api_docs']) to the limit_queue config property, but the schema defined in entityqueue.schema.yml declares it as type: sequence, which expects a numerically-indexed array. This mismatch causes the exception.
Sites whose Views had no limit_queue value configured are unaffected. The failure only occurs on sites with at least one View using the entityqueue relationship filter with a queue selected.
Possible fixes:
- Change the schema from
type: sequencetotype: mapping(ortype: ignore) to match the associative array structure the post-update hook writes. - Replace
ConfigEntityUpdater/$view->save()with direct config factory writes using$config->save(TRUE)(the trusted-data flag that bypassesConfigSchemaChecker).
Workaround: Pin to 1.10.x by adding a Composer conflict for 1.11.*:
"conflict": {
"drupal/entityqueue": "1.11.*"
}
Environment: Drupal 11.3.x, entityqueue 1.11.0, drush 13.x.
Issue fork entityqueue-3610768
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #4
amateescu commentedNice find! Can you try the MR and let me know if it fixes the upgrade path?
Comment #5
amateescu commentedI found and reproduced the exact issue you bumped into, and it was caused by very old views that haven't been touched in years, and contained stale configuration.
Also found a similar problem in the smartqueue module, so I fixed that one as well.
Comment #7
amateescu commentedMerged into 8.x-1.x.
Comment #9
bdanin commentedMaybe merging auto-closes the ticket? I will review. It seems like at this point the easiest way to review is by installing the dev version of this module.
Comment #10
amateescu commentedYes, that's the easiest way to test it now :)
Comment #11
bdanin commentedThe fix in commit 2d31d618 does not resolve the issue. The post-update hook
entityqueue_post_update_relationship_limit_queue_liststill fails because it usesConfigEntityUpdater, which internally calls$view->save()with full schema validation enabled.Two failure modes observed:
1. When
limit_queueis a scalar string ornull, the hook normalizes the value to a list and then calls$view->save(), which immediately throws:2. After manually pre-fixing the
limit_queuevalue via\Drupal::configFactory()->getEditable(...)->save(TRUE), theConfigEntityUpdatercontinues iterating and hits a separate view with:The root problem is that
ConfigEntityUpdateris the wrong tool here — it triggers schema validation on save, which is exactly the thing that breaks during this upgrade path. As discussed earlier in this issue, the correct approach is to write directly to the config factory with the trusted-data flag (->save(TRUE)) to bypass schema validation during the update, similar to how other upgrade hooks handle schema migrations.Comment #12
amateescu commented@bdanin, I wouldn't rely on the trusted data concept because it's being deprecated in core, see https://www.drupal.org/node/3348180, so the only reliable solution is to ensure that the changes to the view made in the update function result in a fully functional and valid view.
Can you please attach the yml config of the problematic view, so I can see exactly what's going wrong?
Comment #13
bdanin commentedThanks for the note on trusted data.
Update on our situation: the default database — which had
limit_queue: blog_top_articlesas a plain scalar string — actually completes the update without error. So the hook does handle that case correctly.The failure we are still hitting is on a separate database in our multisite setup, where a
views.view.*config entry exists in the database with a missingidfield (corrupted config). BecauseConfigEntityUpdatercallsloadMultiple()on all views, it crashes immediately with:This happens before any
limit_queuenormalization is attempted. The fix needed is for the hook to handle (or skip) view configs that cannot be loaded as valid entities, so that one corrupted view does not abort the entire update.Comment #14
amateescu commentedThat's good news, at least for this issue.
On the view with a missing ID, I don't think we can (or even should, if possible) do something about it in the entityqueue update hook, because we can't influence the entity loading process from
ConfigEntityUpdater. But it should be a straightforward fix on that site though: just set an ID for that view in config, and run config import before running database updates (asdrush deploydoes by default).Setting the status back to fixed since there's no additional work to do on the Entityqueue side. I'll release a new version soon with this fix included.
Comment #16
bdanin commentedMakes sense, I agree and thank you :)
Comment #17
amateescu commentedThe new release is out: https://www.drupal.org/project/entityqueue/releases/8.x-1.12