ankane/searchkick · error · ArgumentError

Full reindex does not support :queue mode - use :async mode

Error message

Full reindex does not support :queue mode - use :async mode instead

What it means

mode: :queue pushes record ids onto a Redis queue for a background worker to bulk-process, so it can only reindex the record's full search data. Passing method_name - a partial reindex such as reindex(:search_data) or reindex(some_serializer_method) - together with mode: :queue raises Error 'Partial reindex not supported with queue option', because the queued job would not know which method to call.

Source

Thrown at lib/searchkick/index.rb:365

    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,
        scope: scope,

View on GitHub (pinned to 93e901a75b)

Solutions

  1. Drop the method name so full search data is queued: records.reindex(mode: :queue)
  2. Keep the partial reindex but use mode: :async - Active Job reindex jobs support method_name
  3. Refactor the method's data into search_data so a full reindex produces the same result

Example fix

# before
Product.reindex(:search_data, mode: :queue)
# => Searchkick::Error: Partial reindex not supported with queue option

# after - choose one
Product.reindex(mode: :queue)                 # full reindex via queue
Product.reindex(:search_data, mode: :async)   # partial via Active Job
Defensive patterns

Strategy: validation

Validate before calling

def schedule_reindex(records, method_name: nil, mode:)
  if mode == :queue
    raise ArgumentError, 'partial reindex unsupported with :queue' if method_name
    records.reindex(mode: :queue)
  else
    records.reindex(method_name, mode: mode)
  end
end

Prevention

When it happens

Trigger: Product.reindex(:now_index, mode: :queue); Product.where(active: true).reindex(:search_data, mode: :queue) - any method-name argument combined with queue mode.

Common situations: Switching an existing partial reindex call (used to refresh denormalized index data) to queue mode for performance; adding queue_name to a model and forgetting a call site that passes a method name.

Related errors


AI-assisted analysis of ankane/searchkick@93e901a75b (2026-08-21). Data as JSON: /api/errors/c568dd04f8217e30. Report an issue: GitHub.