ankane/searchkick · error · Searchkick::Error

No index to resume

Error message

No index to resume

What it means

RecordIndexer#reindex accepts only mode: :async, :queue, true, or :inline (true and :inline reindex in the current process). Anything else - unknown symbols, strings, or nil - raises ArgumentError 'Invalid value for mode' before any work starts.

Source

Thrown at lib/searchkick/index.rb:369

    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,
        job_options: job_options
      }

      uuid = index.uuid

View on GitHub (pinned to 93e901a75b)

Solutions

  1. Use one of :async, :queue, :inline (or true)
  2. Normalize the value before calling: mode = mode.presence_in(%w[async queue inline])&.to_sym || :inline
  3. Default the config value explicitly so nil never reaches reindex

Example fix

# before
Product.reindex(mode: ENV['REINDEX_MODE']) # nil or 'background'
# => ArgumentError: Invalid value for mode

# after
mode = ENV['REINDEX_MODE'].presence_in(%w[async queue inline])&.to_sym || :inline
Product.reindex(mode: mode)
Defensive patterns

Strategy: validation

Validate before calling

VALID_MODES = %i[async queue inline].freeze

mode = mode.to_s.presence_in(VALID_MODES.map(&:to_s))&.to_sym || :inline
Product.reindex(mode: mode)

Prevention

When it happens

Trigger: Product.reindex(mode: :background) (a name guessed or carried over from other tooling), mode: :bulk, mode: nil, or mode: 'async' (a string) coming from an interpolated config value.

Common situations: Reading the mode from ENV or YAML config that can be nil or a string; renaming modes after a Searchkick upgrade; copying documentation that uses a mode not supported in the installed version.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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