fix(plugin-search): locale race condition during multi-collection reindex#15738
Open
tolszak wants to merge 1 commit intopayloadcms:mainfrom
Open
fix(plugin-search): locale race condition during multi-collection reindex#15738tolszak wants to merge 1 commit intopayloadcms:mainfrom
tolszak wants to merge 1 commit intopayloadcms:mainfrom
Conversation
…ndex The reindex handler uses Promise.all to process multiple collections concurrently, but all concurrent operations share the same req object. The Payload local API mutates req.locale in-place inside createLocalReq before each async DB operation. When collections are at different locale phases, concurrent createLocalReq calls overwrite req.locale with different values mid-operation, causing documents to be stored under the wrong locale in the search_locales table. Fix by grouping operations by locale phase: process all collections in parallel within the same locale, then move to the next locale. Since all concurrent operations set req.locale to the same value, the in-place mutation becomes idempotent and the race condition is eliminated.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes a race condition in the search plugin's reindex handler where
req.localegets corrupted when multiple collections are reindexed concurrently viaPromise.all.Root Cause
generateReindexHandlerprocesses all collections concurrently usingPromise.all. Each collection iterates through locales, callingsyncDocAsSearchIndexwhich triggers Payload local API calls (findByID,create,update). These calls invokecreateLocalReq, which mutatesreq.localein-place before yielding atawait getLocalI18n().When two collections are at different locale phases (e.g., collection A processing
enwhile collection B processingpl), concurrentcreateLocalReqcalls overwrite each other'sreq.locale. This causes the Drizzle adapter to write documents under the wrong locale insearch_locales— for example, an English title stored as_locale='pl', leaving theenrow empty.The bug is non-deterministic: it depends on which async operations interleave at yield points, so it manifests as random documents missing titles in specific locales after a full reindex.
Fix
Restructure the reindex to process one locale phase at a time, with all collections running in parallel within the same locale:
Since all concurrent operations within a phase set
req.localeto the same value, the in-place mutation becomes idempotent and the race condition is eliminated — while preserving collection-level parallelism.