{"record":{"id":"d309dd2c1c4d660f","repo":"instructure/canvas-lms","slug":"needs-self-item-class-to-be-set-in-self","errorCode":null,"errorMessage":"Needs self.item_class to be set in #{self}","messagePattern":"Needs self\\.item_class to be set in #(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/models/importers.rb","lineNumber":50,"sourceCode":"\n  def self.disable_live_events!\n    ActiveRecord::Base.observers.disable LiveEventsObserver\n    yield\n  ensure\n    enable_live_events!\n  end\n\n  def self.enable_live_events!\n    ActiveRecord::Base.observers.enable LiveEventsObserver\n  end\n\n  class Importer\n    class << self\n      attr_accessor :item_class\n\n      # forward translations to CalendarEvent; they used to live there.\n      def translate(*)\n        raise \"Needs self.item_class to be set in #{self}\" unless item_class\n\n        item_class.translate(*)\n      end\n      alias_method :t, :translate\n\n      def logger(*)\n        raise \"Needs self.item_class to be set in #{self}\" unless item_class\n\n        item_class.logger(*)\n      end\n    end\n  end\n\n  register_content_importer(AccountContentImporter)\n  register_content_importer(CourseContentImporter)\nend\n","sourceCodeStart":32,"sourceCodeEnd":67,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/models/importers.rb#L32-L67","documentation":"Importers::Importer subclasses forward class-level helpers (translate/t) to their item_class, but only if item_class is set via the class-level accessor. Calling translate on a subclass whose item_class was never assigned raises this RuntimeError naming the offending class, because there is no target to forward the call to.","triggerScenarios":"Calling SomeImporter.translate (or .t) on an importer subclass that defines no self.item_class = '...' assignment — typically a newly written or partially ported importer that relies on the inherited translate without registering its item class.","commonSituations":"Writing a new content importer and forgetting `item_class 'DiscussionTopic'` (or equivalent) in the class body; older importer classes predating the item_class refactor being invoked through the new forwarding path.","solutions":["Add an item_class declaration to the importer class, e.g. item_class 'CalendarEvent', inside the subclass body","If the class shouldn't forward translations, override translate/logger locally instead of relying on the shared implementation","Check git history for importer classes that lost their item_class assignment during a refactor"],"exampleFix":"// before\nclass Importers::DiscussionTopicImporter < Importers::Importer\nend\n// after\nclass Importers::DiscussionTopicImporter < Importers::Importer\n  item_class 'DiscussionTopic'\nend","handlingStrategy":"validation","validationCode":"raise 'importer missing item_class' unless MyImporter.item_class","typeGuard":"def usable_importer?(klass)\n  klass.is_a?(Class) && klass < Importers::Importer && !klass.item_class.nil?\nend","tryCatchPattern":"begin\n  importer.translate(payload)\nrescue RuntimeError => e\n  raise unless e.message.start_with?('Needs self.item_class')\n  Rails.logger.error(\"misconfigured importer: #{e.message}\")\nend","preventionTips":["Always declare item_class immediately when subclassing Importers::Importer","Add a boot-time check iterating Importers::Importer subclasses asserting item_class is set","Note it in the importer template/scaffold"],"tags":["ruby","import","configuration","canvas"],"backgroundTag":"missing-required-config-field","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}