ElasticIndexBulkCronWorker throwing NoMethodError for epics
Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.
Summary
Found while looking at the Advanced search dashboard in kibana.
There is a NoMethodError being thrown when epics are indexed into Elasticsearch
Steps to reproduce
Not confirmed, but I suspect this can be reproduced by indexing an epic with a group that does not have a root ancestor
What is the current bug behavior?
Indexing fails
What is the expected correct behavior?
Indexing should succeed
Relevant logs and/or screenshots
kibana search for error: https://log.gprd.gitlab.net/app/r/s/PZvS3
backtrace
[app/models/preloaders/group_root_ancestor_preloader.rb:20:in `block in execute', app/models/preloaders/group_root_ancestor_preloader.rb:19:in `each', app/models/preloaders/group_root_ancestor_preloader.rb:19:in `execute', ee/lib/elastic/latest/epic_class_proxy.rb:37:in `preload_indexing_data', ee/lib/elastic/multi_version_util.rb:76:in `preload_indexing_data', ee/app/models/concerns/elastic/application_versioned_search.rb:52:in `block (2 levels) in <module:ApplicationVersionedSearch>', activerecord (7.0.8.1) lib/active_record/relation.rb:435:in `instance_exec', activerecord (7.0.8.1) lib/active_record/relation.rb:435:in `block in _exec_scope', activerecord (7.0.8.1) lib/active_record/relation.rb:881:in `_scoping', activerecord (7.0.8.1) lib/active_record/relation.rb:435:in `_exec_scope', activerecord (7.0.8.1) lib/active_record/scoping/named.rb:175:in `block in scope', activerecord (7.0.8.1) lib/active_record/relation/delegation.rb:67:in `block in preload_indexing_data', activerecord (7.0.8.1) lib/active_record/relation.rb:881:in `_scoping', activerecord (7.0.8.1) lib/active_record/relation.rb:428:in `scoping', activerecord (7.0.8.1) lib/active_record/relation/delegation.rb:67:in `preload_indexing_data', ee/lib/gitlab/elastic/document_reference.rb:65:in `block in preload_indexing_data', ee/lib/gitlab/elastic/document_reference.rb:62:in `each', ee/lib/gitlab/elastic/document_reference.rb:62:in `preload_indexing_data', ee/lib/search/elastic/reference.rb:75:in `block (2 levels) in preload_database_records', ee/lib/search/elastic/reference.rb:74:in `each', ee/lib/search/elastic/reference.rb:74:in `each_slice', ee/lib/search/elastic/reference.rb:74:in `block in preload_database_records', ee/lib/search/elastic/reference.rb:73:in `each', ee/lib/search/elastic/reference.rb:73:in `preload_database_records', ee/app/services/elastic/process_bookkeeping_service.rb:186:in `execute_with_redis', ee/app/services/elastic/process_bookkeeping_service.rb:148:in `block in execute', lib/gitlab/redis/wrapper.rb:26:in `block in with', connection_pool (2.4.1) lib/connection_pool.rb:110:in `block (2 levels) in with', connection_pool (2.4.1) lib/connection_pool.rb:109:in `handle_interrupt', connection_pool (2.4.1) lib/connection_pool.rb:109:in `block in with', connection_pool (2.4.1) lib/connection_pool.rb:106:in `handle_interrupt', connection_pool (2.4.1) lib/connection_pool.rb:106:in `with', lib/gitlab/redis/wrapper.rb:26:in `with', ee/app/services/elastic/process_bookkeeping_service.rb:106:in `with_redis', ee/app/services/elastic/process_bookkeeping_service.rb:148:in `execute', ee/app/workers/concerns/elastic/bulk_cron_worker.rb:50:in `block in process_shard', lib/gitlab/exclusive_lease_helpers.rb:43:in `block in in_lock', lib/gitlab/exclusive_lease_helpers.rb:53:in `with_instrumentation', lib/gitlab/exclusive_lease_helpers.rb:42:in `in_lock', ee/app/workers/concerns/elastic/bulk_cron_worker.rb:49:in `process_shard', ee/app/workers/concerns/elastic/bulk_cron_worker.rb:34:in `perform', ee/app/workers/concerns/geo/skip_secondary.rb:14:in `perform', vendor/gems/sidekiq-7.1.6/lib/sidekiq/processor.rb:210:in `execute_job', vendor/gems/sidekiq-7.1.6/lib/sidekiq/processor.rb:180:in `block (4 levels) in process', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:180:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', lib/gitlab/sidekiq_middleware/skip_jobs.rb:51:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', lib/gitlab/database/load_balancing/sidekiq_server_middleware.rb:29:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', lib/gitlab/sidekiq_middleware/duplicate_jobs/strategies/until_executing.rb:16:in `perform', lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb:44:in `perform', lib/gitlab/sidekiq_middleware/duplicate_jobs/server.rb:8:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', lib/gitlab/sidekiq_middleware/concurrency_limit/middleware.rb:32:in `perform', lib/gitlab/sidekiq_middleware/concurrency_limit/server.rb:8:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', lib/click_house/migration_support/sidekiq_middleware.rb:7:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', lib/gitlab/sidekiq_middleware/pause_control/strategies/base.rb:31:in `perform', lib/gitlab/sidekiq_middleware/pause_control/strategy_handler.rb:22:in `perform', lib/gitlab/sidekiq_middleware/pause_control/server.rb:8:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', lib/gitlab/application_context.rb:133:in `block in use', gitlab-labkit (0.36.0) lib/labkit/context.rb:35:in `with_context', lib/gitlab/application_context.rb:133:in `use', lib/gitlab/sidekiq_middleware/worker_context.rb:11:in `wrap_in_optional_context', lib/gitlab/sidekiq_middleware/worker_context/server.rb:19:in `block in call', lib/gitlab/application_context.rb:133:in `block in use', gitlab-labkit (0.36.0) lib/labkit/context.rb:35:in `with_context', lib/gitlab/application_context.rb:133:in `use', lib/gitlab/application_context.rb:66:in `with_context', lib/gitlab/sidekiq_middleware/worker_context/server.rb:17:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', lib/gitlab/sidekiq_status/server_middleware.rb:7:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', lib/gitlab/sidekiq_versioning/middleware.rb:9:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', lib/gitlab/sidekiq_middleware/query_analyzer.rb:7:in `block in call', lib/gitlab/database/query_analyzer.rb:40:in `within', lib/gitlab/sidekiq_middleware/query_analyzer.rb:7:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', lib/gitlab/sidekiq_middleware/admin_mode/server.rb:14:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', lib/gitlab/sidekiq_middleware/instrumentation_logger.rb:9:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', lib/gitlab/sidekiq_middleware/batch_loader.rb:7:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', lib/gitlab/sidekiq_middleware/extra_done_log_metadata.rb:7:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', lib/gitlab/sidekiq_middleware/server_metrics.rb:111:in `block in call', lib/gitlab/sidekiq_middleware/server_metrics.rb:139:in `block in instrument', lib/gitlab/metrics/background_transaction.rb:33:in `run', lib/gitlab/sidekiq_middleware/server_metrics.rb:139:in `instrument', lib/gitlab/sidekiq_middleware/server_metrics.rb:110:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', lib/gitlab/sidekiq_middleware/request_store_middleware.rb:8:in `block in call', gems/gitlab-safe_request_store/lib/gitlab/safe_request_store.rb:66:in `enabling_request_store', gems/gitlab-safe_request_store/lib/gitlab/safe_request_store.rb:59:in `ensure_request_store', lib/gitlab/sidekiq_middleware/request_store_middleware.rb:7:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', gitlab-labkit (0.36.0) lib/labkit/middleware/sidekiq/server.rb:21:in `block in call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:180:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', gitlab-labkit (0.36.0) lib/labkit/middleware/sidekiq/context/server.rb:16:in `block in call', gitlab-labkit (0.36.0) lib/labkit/context.rb:35:in `with_context', gitlab-labkit (0.36.0) lib/labkit/middleware/sidekiq/context/server.rb:15:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:173:in `invoke', gitlab-labkit (0.36.0) lib/labkit/middleware/sidekiq/server.rb:20:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', lib/gitlab/sidekiq_middleware/monitor.rb:10:in `block in call', lib/gitlab/sidekiq_daemon/monitor.rb:46:in `within_job', lib/gitlab/sidekiq_middleware/monitor.rb:9:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', lib/gitlab/sidekiq_middleware/shard_awareness_validator.rb:10:in `block in call', lib/gitlab/sidekiq_sharding/validator.rb:42:in `enabled', lib/gitlab/sidekiq_middleware/shard_awareness_validator.rb:9:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', lib/gitlab/sidekiq_middleware/size_limiter/server.rb:13:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', marginalia (1.11.1) lib/marginalia/sidekiq_instrumentation.rb:9:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', sentry-sidekiq (5.17.3) lib/sentry/sidekiq/sentry_context_middleware.rb:26:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:183:in `block in traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/metrics/tracking.rb:26:in `track', vendor/gems/sidekiq-7.1.6/lib/sidekiq/metrics/tracking.rb:122:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:182:in `traverse', vendor/gems/sidekiq-7.1.6/lib/sidekiq/middleware/chain.rb:173:in `invoke', vendor/gems/sidekiq-7.1.6/lib/sidekiq/processor.rb:179:in `block (3 levels) in process', vendor/gems/sidekiq-7.1.6/lib/sidekiq/processor.rb:140:in `block (6 levels) in dispatch', vendor/gems/sidekiq-7.1.6/lib/sidekiq/job_retry.rb:114:in `local', vendor/gems/sidekiq-7.1.6/lib/sidekiq/processor.rb:139:in `block (5 levels) in dispatch', vendor/gems/sidekiq-7.1.6/lib/sidekiq/rails.rb:16:in `block in call', activesupport (7.0.8.1) lib/active_support/execution_wrapper.rb:92:in `wrap', activesupport (7.0.8.1) lib/active_support/reloader.rb:72:in `block in wrap', activesupport (7.0.8.1) lib/active_support/execution_wrapper.rb:92:in `wrap', activesupport (7.0.8.1) lib/active_support/reloader.rb:71:in `wrap', vendor/gems/sidekiq-7.1.6/lib/sidekiq/rails.rb:15:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/processor.rb:135:in `block (4 levels) in dispatch', vendor/gems/sidekiq-7.1.6/lib/sidekiq/processor.rb:271:in `stats', vendor/gems/sidekiq-7.1.6/lib/sidekiq/processor.rb:130:in `block (3 levels) in dispatch', lib/gitlab/sidekiq_logging/structured_logger.rb:21:in `call', vendor/gems/sidekiq-7.1.6/lib/sidekiq/processor.rb:129:in `block (2 levels) in dispatch', vendor/gems/sidekiq-7.1.6/lib/sidekiq/job_retry.rb:81:in `global', vendor/gems/sidekiq-7.1.6/lib/sidekiq/processor.rb:128:in `block in dispatch', vendor/gems/sidekiq-7.1.6/lib/sidekiq/job_logger.rb:39:in `prepare', vendor/gems/sidekiq-7.1.6/lib/sidekiq/processor.rb:127:in `dispatch', vendor/gems/sidekiq-7.1.6/lib/sidekiq/processor.rb:178:in `block (2 levels) in process', vendor/gems/sidekiq-7.1.6/lib/sidekiq/processor.rb:177:in `handle_interrupt', vendor/gems/sidekiq-7.1.6/lib/sidekiq/processor.rb:177:in `block in process', vendor/gems/sidekiq-7.1.6/lib/sidekiq/processor.rb:176:in `handle_interrupt', vendor/gems/sidekiq-7.1.6/lib/sidekiq/processor.rb:176:in `process', vendor/gems/sidekiq-7.1.6/lib/sidekiq/processor.rb:82:in `process_one', vendor/gems/sidekiq-7.1.6/lib/sidekiq/processor.rb:72:in `run', vendor/gems/sidekiq-7.1.6/lib/sidekiq/component.rb:10:in `watchdog', vendor/gems/sidekiq-7.1.6/lib/sidekiq/component.rb:19:in `block in safe_thread']
exception message
undefined method `first' for nil:NilClass
group.root_ancestor = root_ancestors_by_id[group.id].first
^^^^^^
Possible fixes
The error is being thrown in ElasticIndexBulkCronWorker from Preloaders::GroupRootAncestorPreloader which is called in EpicClassProxy
Edited by 🤖 GitLab Bot 🤖
