Fix: gate traversal_ids on commits in ES indexer behind AddTraversalIdsToCommits migration
Summary
The gitlab-elasticsearch-indexer (Go binary) unconditionally writes traversal_ids into commit documents when the field is provided via --traversal-ids. However, the commits index mapping does not have traversal_ids until the AddTraversalIdsToCommits migration (20260216152309) has finished. Because GitLab Advanced Search uses strict mapping, Elasticsearch/OpenSearch will reject any commit document that includes an unmapped field, causing indexing errors for all commits until the migration completes.
Additionally, a backfill migration (BackfillTraversalIdsOnCommits, 20260216153009) exists to populate traversal_ids on already-indexed commits after the mapping is in place — but this backfill is also not gated correctly.
Steps to reproduce
- Have an instance where
AddTraversalIdsToCommitsmigration has not yet finished. - Trigger any commit indexing (e.g. push to a repository with Advanced Search enabled).
- Observe errors from the Go indexer: Elasticsearch rejects the commit document due to
traversal_idsnot being present in the index mapping.
What is the current bug behavior?
ee/lib/gitlab/elastic/indexer.rb unconditionally passes --traversal-ids=<value> to the Go binary for all indexing calls. The Go binary then writes traversal_ids into every commit document. If the AddTraversalIdsToCommits mapping migration has not finished, Elasticsearch/OpenSearch rejects those documents with a mapping error.
Relevant code path:
build_commandinee/lib/gitlab/elastic/indexer.rbalways appends--traversal-ids=...submitCommitininternal/mode/advanced/indexer/indexer.gowritestraversal_idsonto the commit body whenever the flag value is non-empty- The mapping migration
20260216152309_add_traversal_ids_to_commits.rbmust complete beforetraversal_idscan be written to commit documents
What is the expected correct behavior?
The Go indexer should only write traversal_ids onto commit documents once the AddTraversalIdsToCommits mapping migration has finished.
The fix requires changes in two repositories:
gitlab-org/gitlab-elasticsearch-indexer
Add a new boolean CLI flag --commit-traversal-ids-enabled. When this flag is absent or false, the indexer must not set traversal_ids on commit documents (but should continue setting it on blobs and wiki blobs, where the mapping already exists).
gitlab-org/gitlab
In build_blob_specific_flags (or build_command) inside ee/lib/gitlab/elastic/indexer.rb, gate the --commit-traversal-ids-enabled flag behind:
migration_finished?(:add_traversal_ids_to_commits)Only pass --commit-traversal-ids-enabled to the Go binary once that migration has completed.
Relevant logs and/or screenshots
Elasticsearch/OpenSearch error when strict mapping rejects an unmapped field:
{"type":"strict_dynamic_mapping_exception","reason":"mapping set to strict, dynamic introduction of [traversal_ids] within [_doc] is not allowed"}Possible fixes
- Add
--commit-traversal-ids-enabledboolean flag to the Go indexer (internal/mode/advanced/advanced.go, threaded throughelastic.Config,elastic.Client, and theSubmitterinterface) - Gate the flag in
submitCommit(indexer.go) sotraversal_idsis only added to commit bodies when the flag istrue - In
ee/lib/gitlab/elastic/indexer.rb, pass--commit-traversal-ids-enabledonly whenmigration_finished?(:add_traversal_ids_to_commits)returnstrue