{"record":{"id":"8e0ce0de607e518a","repo":"bensheldon/good_job","slug":"performer-argument-must-implement-next","errorCode":null,"errorMessage":"Performer argument must implement #next","messagePattern":"Performer argument must implement #next","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/good_job/scheduler.rb","lineNumber":57,"sourceCode":"    cattr_reader :instances, default: Concurrent::Array.new, instance_reader: false\n\n    # Human readable name of the scheduler that includes configuration values.\n    # @return [String]\n    attr_reader :name\n\n    # Whether to lower the thread priority to a fixed value\n    # @return [Boolean]\n    attr_accessor :lower_thread_priority\n\n    # @param performer [GoodJob::JobPerformer]\n    # @param max_threads [Numeric, nil] number of seconds between polls for jobs\n    # @param max_cache [Numeric, nil] maximum number of scheduled jobs to cache in memory\n    # @param warm_cache_on_initialize [Boolean] whether to warm the cache immediately, or manually by calling +warm_cache+\n    # @param cleanup_interval_seconds [Numeric, nil] number of seconds between cleaning up job records\n    # @param cleanup_interval_jobs [Numeric, nil] number of executed jobs between cleaning up job records\n    # @param lower_thread_priority [Boolean] whether to lower the thread priority of execution threads\n    def initialize(performer, max_threads: nil, max_cache: nil, warm_cache_on_initialize: false, cleanup_interval_seconds: nil, cleanup_interval_jobs: nil, lower_thread_priority: false)\n      raise ArgumentError, \"Performer argument must implement #next\" unless performer.respond_to?(:next)\n\n      @performer = performer\n\n      @max_cache = max_cache || 0\n      @executor_options = DEFAULT_EXECUTOR_OPTIONS.dup\n      if max_threads.present?\n        @executor_options[:max_threads] = max_threads\n        @executor_options[:max_queue] = max_threads\n      end\n      @name = \"GoodJob::Scheduler(queues=#{@performer.name} max_threads=#{@executor_options[:max_threads]})\"\n      @executor_options[:name] = name\n\n      @cleanup_tracker = CleanupTracker.new(cleanup_interval_seconds: cleanup_interval_seconds, cleanup_interval_jobs: cleanup_interval_jobs)\n      @executor_options[:name] = name\n\n      self.lower_thread_priority = lower_thread_priority\n\n      create_executor","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/bensheldon/good_job/blob/5fcde48f8765e69901ffa9c5a06122b19c73875f/lib/good_job/scheduler.rb#L39-L75","documentation":"Error \"Performer argument must implement #next\" thrown in bensheldon/good_job.","triggerScenarios":"Thrown at lib/good_job/scheduler.rb:57 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Pass a performer object that responds to #next to GoodJob::Scheduler.","Use an object implementing #next, such as GoodJob::JobPerformer."],"exampleFix":"GoodJob::Scheduler.new(GoodJob::JobPerformer.new('*'))","handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"5fcde48f8765e69901ffa9c5a06122b19c73875f","analyzedAt":"2026-08-23T14:55:11.399Z","schemaVersion":2},"datasetVersion":"2026-08-23T16:17:53.355Z"}