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.

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.

Appendix: 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)