ankane/searchkick · error · ArgumentError
wait only available in :async mode
Error message
wait only available in :async mode
What it means
mode: :async reindexing enqueues jobs through Active Job (ReindexV2Job, BulkReindexJob, ProcessBatchJob). RecordIndexer checks defined?(ActiveJob) and raises Error 'Active Job not found' when it is not loaded - typically when Searchkick is used outside full Rails or in an app that skipped Active Job.
Source
Thrown at lib/searchkick/index.rb:364
end
def import_before_promotion(index, relation, **import_options)
index.import_scope(relation, **import_options)
end
def reindex_records(object, mode: nil, refresh: false, **options)
mode ||= Searchkick.callbacks_value || @options[:callbacks] || :inline
mode = :inline if mode == :bulk
result = RecordIndexer.new(self).reindex(object, mode: mode, full: false, **options)
self.refresh if refresh
result
end
# https://gist.github.com/jarosan/3124884
# https://www.elastic.co/blog/changing-mapping-with-zero-downtime/
def full_reindex(relation, import: true, resume: false, retain: false, mode: nil, refresh_interval: nil, scope: nil, wait: nil, job_options: nil)
raise ArgumentError, "wait only available in :async mode" if !wait.nil? && mode != :async
raise ArgumentError, "Full reindex does not support :queue mode - use :async mode instead" if mode == :queue
if resume
index_name = all_indices.sort.last
raise Error, "No index to resume" unless index_name
index = Index.new(index_name, @options)
else
clean_indices unless retain
index_options = relation.searchkick_index_options
index_options.deep_merge!(settings: {index: {refresh_interval: refresh_interval}}) if refresh_interval
index = create_index(index_options: index_options)
end
import_options = {
mode: (mode || :inline),
full: true,
resume: resume,View on GitHub (pinned to 93e901a75b)
Solutions
- Load Active Job and pick a queue adapter: require 'active_job' and set config.active_job.queue_adapter = :sidekiq (or :inline for scripts)
- If jobs are not an option, use mode: :inline (same process) or mode: :queue with Redis
- In Rails, ensure the full application environment is booted (rails runner, app tasks) before calling reindex(mode: :async)
Example fix
# before Product.reindex(mode: :async) # plain ruby / Sinatra, no ActiveJob loaded # => Searchkick::Error: Active Job not found # after require 'active_job' ActiveJob::Base.queue_adapter = :inline # or :async / :sidekiq Product.reindex(mode: :async)
Defensive patterns
Strategy: validation
Validate before calling
def reindex_async?(mode) return false unless mode == :async raise 'Active Job not available' unless defined?(ActiveJob) true end mode = reindex_async?(:async) ? :async : :inline Product.reindex(mode: mode)
Try / catch
begin Product.reindex(mode: :async) rescue Searchkick::Error # no ActiveJob in this context - degrade to inline Product.reindex(mode: :inline) end
Prevention
- Boot-check dependencies: fail fast at startup if :async mode is configured but ActiveJob is missing
- In non-Rails scripts, require 'active_job' and set a queue adapter before any reindex
- Prefer mode: :queue (Redis) where ActiveJob is unavailable
When it happens
Trigger: Product.reindex(mode: :async) from a standalone Ruby script, Sinatra app, or a boot path where Active Job was never required; a Gemfile without rails/activejob while code still uses :async mode.
Common situations: Adding background reindexing in a non-Rails project; a test harness that boots only activerecord; a Rails app generated with --skip-active-job; running rake tasks before the Rails environment is loaded.
Related errors
- Full reindex does not support :queue mode - use :async mode
- No index to resume
- knn requires OpenSearch 2.4+
- #{first_with_error["error"]} on item with id '#{first_with_e
- The `conversions` option is deprecated in favor of `conversi
AI-assisted analysis of ankane/searchkick@93e901a75b (2026-08-21).
Data as JSON: /api/errors/918454f1aa0569b3.
Report an issue: GitHub.