instructure/canvas-lms · error · NoMethodError
Subclasses must implement #process_batch when mode is :batch
Error message
Subclasses must implement #process_batch when mode is :batch
What it means
NoMethodError raised by the DataFixup#process_batch stub. In :batch mode, process_range delegates whole batches to process_batch, which is abstract — subclasses must implement it. This is a template-method enforcement error, not a runtime data problem.
Solutions
- Implement def process_batch(batch) ... end in the subclass, processing the scope in bulk (e.g. update_all)
- Alternatively set self.mode = :individual_record and implement process_record instead
- Check the mode and method names match the intended processing strategy
Example fix
// before self.mode = :batch # no process_batch defined // after self.mode = :batch def process_batch(batch) batch.update_all(status: 'fixed') end
Defensive patterns
Strategy: validation
Validate before calling
raise 'process_batch required' if mode == :batch && instance_method(:process_batch).owner == CanvasOperations::DataFixup
Try / catch
rescue NoMethodError => e
raise unless e.message.include?('process_batch')
Rails.logger.error('Subclass must implement process_batch for :batch mode')
end Prevention
- Implement process_batch whenever setting mode = :batch
- Use inheritance checks/lint rules for abstract methods in fixups
- Smoke-test new fixups against a small scope before full runs
When it happens
Trigger: Defining self.mode = :batch on a DataFixup subclass but not overriding process_batch; running a subclass written for the default :individual_record mode after switching it to :batch.
Common situations: Converting a slow per-record fixup to batch mode but only renaming process_record; forgetting the override when copy-pasting a new fixup skeleton.
Understand the failure class
Background: "NotImplementedError: Subclasses should override this method" / "must be implemented" — abstract method errors explained — this error's family across 40 libraries.
Related errors
- Subclasses must implement #process_record when mode is…
- Invalid mode: #
- No question type used when trying to parse a qti question
- progress_tracking must be a boolean
- setting_name cannot be nil
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/4d3ef36e79533453.
Report an issue: GitHub.
Appendix: source
Thrown at lib/canvas_operations/data_fixup.rb:142
#
# Defaults to `true`, which means the data fixup will run on the default shard.
attr_writer :run_on_default_shard
def run_on_default_shard?
@run_on_default_shard.nil? || @run_on_default_shard
end
end
protected
# Processes a batch of records. Ideal for making bulk updates to
# entire batches of rows that don't need to be individually loaded / processed.
#
# Subclasses must implement this method to define how to process a batch of records
#
# Only used when mode is set to :batch.
def process_batch(_batch)
raise NoMethodError, "Subclasses must implement #process_batch when mode is :batch"
end
# Processes an individual record. Ideal for when each record needs to be
# loaded and processed separately.
#
# Subclasses must implement this method to define how to process an individual record.
#
# Only used when mode is set to :individual_record.
def process_record(_record)
raise NoMethodError, "Subclasses must implement #process_record when mode is :individual_record"
end
# Determines if the current shard is a valid target for the DataFixup operation.
#
# In its base form this check returns true unless run_on_default_shard is false,
# in which case it returns true only if the current shard is not the default shard.
#
# Be wary if overriding this method. The default shard contains shadow copies of allView on GitHub (pinned to 1c9f0bb801)