Skip to content

fix(AppDisableListener): pass full provider key to deleteProvider - #265

Merged
kyteinsky merged 1 commit into
nextcloud:mainfrom
weltmaister:fix/appdisable-provider-key
Aug 13, 2026
Merged

fix(AppDisableListener): pass full provider key to deleteProvider#265
kyteinsky merged 1 commit into
nextcloud:mainfrom
weltmaister:fix/appdisable-provider-key

Conversation

@weltmaister

Copy link
Copy Markdown
Contributor

Summary

AppDisableListener schedules a delete_provider_id action using the bare provider id (e.g. mail) instead of the full provider key appId__providerId (e.g. mail__mail). The backend rejects the bare id (is_valid_provider_id, ^[a-zA-Z0-9_-]+__[a-zA-Z0-9_-]+$).

Because context_chat_backend's updates_processing_thread validates the whole ActionsQueueItems batch in a single model_validate() call, this one invalid item makes it throw on every poll and freezes the entire oc_context_chat_action_queue indefinitely — access-declaration updates, deletions, etc. stop propagating and it never recovers on its own.

Details in #258.

Fix

$key already holds the correct full key (appId__providerId), so pass it directly to ActionScheduler::deleteProvider() instead of the split-off $providerId.

Also documented on ActionScheduler::deleteProvider() that it expects the full appId__providerId key (as returned by ProviderConfigService::getConfigKey()), matching every other caller.

Trigger / impact

AppDisableEvent fires whenever an app that registered a content provider is disabled — including during app updates / occ upgrade. The Mail app registers provider id mail, so each disable produced one poisoned delete_provider_id: mail row. Observed effect: 500+ update_access_decl_source_id actions stuck for ~1 day; ACL/share changes not reflected in semantic search until the poison rows were removed manually.

Note

Secondary hardening — updates_processing_thread validating/skipping per item (like the files path already does via ItemValidationError) instead of aborting the whole batch — belongs in context_chat_backend and is out of scope here.

AppDisableListener passed the bare provider id (e.g. "mail") instead of
the full provider key appId__providerId (e.g. "mail__mail") to
ActionScheduler::deleteProvider(). The backend rejects the bare id
(is_valid_provider_id / ^[a-zA-Z0-9_-]+__[a-zA-Z0-9_-]+$), and because it
validates the whole ActionsQueueItems batch in one model_validate() call,
this single poisoned row makes updates_processing_thread throw on every
poll and freezes the entire oc_context_chat_action_queue indefinitely.

The correct full key is already available in $key, so pass it directly.
Also document in ActionScheduler::deleteProvider() that the full
appId__providerId key is expected.

Fixes nextcloud#258

Signed-off-by: weltmaister <55494283+weltmaister@users.noreply.github.com>
@weltmaister
weltmaister force-pushed the fix/appdisable-provider-key branch from 485ec28 to 6bc4101 Compare August 10, 2026 17:05

@kyteinsky kyteinsky left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks!

@kyteinsky
kyteinsky merged commit a9d167c into nextcloud:main Aug 13, 2026
28 of 34 checks passed
@kyteinsky kyteinsky mentioned this pull request Aug 13, 2026
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AppDisableListener enqueues invalid delete_provider_id (bare provider id) → freezes the whole action queue

2 participants