{"record":{"id":"793917a4a1e35940","repo":"ankane/searchkick","slug":"invalid-value-for-callbacks","errorCode":null,"errorMessage":"Invalid value for callbacks","messagePattern":"Invalid value for callbacks","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/searchkick/model.rb","lineNumber":30,"sourceCode":"      end\n\n      unknown_keywords = options.keys - [:_all, :_type, :batch_size, :callbacks, :callback_options, :case_sensitive, :conversions, :conversions_v2, :deep_paging, :default_fields,\n        :filterable, :geo_shape, :highlight, :ignore_above, :index_name, :index_prefix, :inheritance, :job_options, :knn, :language,\n        :locations, :mappings, :match, :max_result_window, :merge_mappings, :routing, :searchable, :search_synonyms, :settings, :similarity,\n        :special_characters, :stem, :stemmer, :stem_conversions, :stem_exclusion, :stemmer_override, :suggest, :synonyms, :text_end,\n        :text_middle, :text_start, :unscope, :word, :word_end, :word_middle, :word_start]\n      raise ArgumentError, \"unknown keywords: #{unknown_keywords.join(\", \")}\" if unknown_keywords.any?\n\n      raise \"Only call searchkick once per model\" if respond_to?(:searchkick_index)\n\n      Searchkick.models << self\n\n      options[:_type] ||= -> { searchkick_index.klass_document_type(self, true) }\n      options[:class_name] = model_name.name\n\n      callbacks = options.key?(:callbacks) ? options[:callbacks] : :inline\n      unless [:inline, true, false, :async, :queue].include?(callbacks)\n        raise ArgumentError, \"Invalid value for callbacks\"\n      end\n      callback_options = (options[:callback_options] || {}).dup\n      callback_options[:if] = [-> { Searchkick.callbacks?(default: callbacks) }, callback_options[:if]].compact.flatten(1)\n\n      base = self\n\n      mod = Module.new\n      include(mod)\n      mod.module_eval do\n        def reindex(method_name = nil, mode: nil, refresh: false, ignore_missing: nil, job_options: nil)\n          self.class.searchkick_index.reindex([self], method_name: method_name, mode: mode, refresh: refresh, ignore_missing: ignore_missing, job_options: job_options, single: true)\n        end unless base.method_defined?(:reindex)\n\n        def similar(**options)\n          self.class.searchkick_index.similar_record(self, **options)\n        end unless base.method_defined?(:similar)\n\n        def search_data","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/ankane/searchkick/blob/93e901a75b11a25101668a616e006b158251b16e/lib/searchkick/model.rb#L12-L48","documentation":"The `callbacks` option controls how searchkick syncs records to the index on save/destroy. It accepts exactly `:inline` (default), `true` (alias of inline), `false` (disable), `:async` (background job), and `:queue` (ActiveJob queue for high-throughput bulk). Anything else — a string, `\"async\"`, `nil`-like values, or a typo — raises `ArgumentError` at class-load time.","triggerScenarios":"`searchkick callbacks: \"async\"` (string instead of symbol), `callbacks: :background`, `callbacks: :sidekiq`, or `callbacks: nil`/`:default` on a model, triggering the check when the class loads.","commonSituations":"Reading older searchkick docs/tutorials where `\"false\"` or other values were shown; setting callbacks from an ENV var or YAML without casting (`callbacks: ENV[\"SEARCHKICK_CALLBACKS\"]` yields a string or nil); renaming from `:async` to `:queue` and typo'ing; wrapping in quotes by copy-paste.","solutions":["Use one of the five valid values: `:inline`, `true`, `false`, `:async`, `:queue`.","When the value comes from config, normalize it: `callbacks: ENV.fetch(\"SEARCHKICK_CALLBACKS\", \"inline\").then { |v| %w[true false].include?(v) ? v == \"true\" : v.to_sym }`.","For `:async`/`:queue`, ensure ActiveJob/Sidekiq is configured (a queue adapter and workers running), since the error often appears while wiring those up.","Check the gem version's README — supported callbacks values have changed across majors."],"exampleFix":"# before\nsearchkick callbacks: ENV[\"SEARCHKICK_CALLBACKS\"] # \"async\" (String) => ArgumentError\n\n# after\nraw = ENV.fetch(\"SEARCHKICK_CALLBACKS\", \"inline\")\ncallbacks = %w[true false].include?(raw) ? raw == \"true\" : raw.to_sym\nsearchkick callbacks: callbacks","handlingStrategy":"validation","validationCode":"VALID_CALLBACKS = [:inline, true, false, :async, :queue]\nraw = ENV.fetch(\"SEARCHKICK_CALLBACKS\", \"inline\")\ncallbacks = %w[true false].include?(raw) ? raw == \"true\" : raw.to_sym\nraise ArgumentError, \"callbacks must be one of #{VALID_CALLBACKS.inspect}\" unless VALID_CALLBACKS.include?(callbacks)\nclass Product < ApplicationRecord\n  searchkick callbacks: callbacks\nend","typeGuard":"def valid_callbacks_value?(v)\n  [:inline, true, false, :async, :queue].include?(v)\nend","tryCatchPattern":null,"preventionTips":["Normalize ENV/YAML-sourced values (to_sym / true-false casting) before passing them in.","Prefer symbols over strings; `\"async\"` is not `:async`.","For :async/:queue, verify a working queue adapter in staging before enabling in production."],"tags":["searchkick","callbacks","configuration","argumenterror"],"backgroundTag":"invalid-option-value","analyzedSha":"93e901a75b11a25101668a616e006b158251b16e","analyzedAt":"2026-08-21T19:06:23.767Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}