{"record":{"id":"498f6254b9c32ad4","repo":"instructure/canvas-lms","slug":"invalid-edit-type","errorCode":null,"errorMessage":"invalid edit type","messagePattern":"invalid edit type","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"app/models/master_courses/restrictor.rb","lineNumber":138,"sourceCode":"      end\n    end\n\n    def editing_restricted?(edit_type = :all) # edit_type can be :all, :any, or a specific type: :content, :settings, :due_dates, :availability_dates, :points\n      return false unless is_child_content?\n\n      restrictions = child_content_restrictions\n      return false unless restrictions.present?\n      return true if restrictions[:all]\n\n      case edit_type\n      when :all\n        self.class.base_class.restricted_column_settings.keys.all? { |type| restrictions[type] } # make it possible to only have restrictions on one type\n      when :any\n        self.class.base_class.restricted_column_settings.keys.any? { |type| restrictions[type] }\n      when *MasterCourses::LOCK_TYPES\n        !!restrictions[edit_type]\n      else\n        raise \"invalid edit type\"\n      end\n    end\n\n    def skip_restrictions?\n      @importing_migration || @skip_downstream_changes || !is_child_content? # don't mark changes on import\n    end\n  end\n\n  def check_restrictions?\n    !new_record?\n  end\n\n  def mark_downstream_changes(changed_columns = nil)\n    return if skip_restrictions?\n\n    changed_columns ||= saved_changes.keys & self.class.base_class.restricted_column_settings.values.flatten\n    state_column = is_a?(Attachment) ? \"file_state\" : \"workflow_state\"\n    if saved_changes[state_column]&.last == \"deleted\"","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/models/master_courses/restrictor.rb#L120-L156","documentation":"editing_restricted?(edit_type) checks whether edits of a given type are locked by the master course. It accepts :all, :any, or one of MasterCourses::LOCK_TYPES; any other value falls through to a raise 'invalid edit type'.","triggerScenarios":"Calling editing_restricted? with an arbitrary symbol/string (e.g. from check_before_overwriting_child_content_on_import or master_course_api_restriction_data passing an unvalidated lock type), or with a lock type removed/renamed in this Canvas version.","commonSituations":"Plugin/custom code passing its own edit type symbol; stale cached lock type lists after a Canvas upgrade; string vs symbol confusion when the caller builds edit_type dynamically.","solutions":["Pass only :all, :any, or symbols listed in MasterCourses::LOCK_TYPES","Validate/normalize the edit_type at the call site before calling editing_restricted?","Grep custom overrides that call editing_restricted? and update them to current lock types"],"exampleFix":"// before\nrecord.editing_restricted?(edit_type_param.to_sym)\n// after\nedit = edit_type_param.to_sym\nraise ArgumentError, 'bad edit type' unless [:all, :any, *MasterCourses::LOCK_TYPES].include?(edit)\nrecord.editing_restricted?(edit)","handlingStrategy":"validation","validationCode":"ALLOWED = [:all, :any, *MasterCourses::LOCK_TYPES]\nrecord.editing_restricted?(edit_type) if ALLOWED.include?(edit_type)","typeGuard":"def editable_restriction_type?(t)\n  t == :all || t == :any || MasterCourses::LOCK_TYPES.include?(t)\nend","tryCatchPattern":"begin\n  restricted = record.editing_restricted?(type)\nrescue RuntimeError => e\n  raise unless e.message == 'invalid edit type'\n  restricted = false\nend","preventionTips":["Never pass user-supplied or dynamically built symbols straight into editing_restricted?","Keep a shared whitelist constant across callers"],"tags":["ruby","blueprint-courses","invalid-argument"],"backgroundTag":"invalid-enum-value","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"}