instructure/canvas-lms · error · RuntimeError

invalid edit type

Error message

invalid edit type

What it means

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'.

Solutions

  1. Pass only :all, :any, or symbols listed in MasterCourses::LOCK_TYPES
  2. Validate/normalize the edit_type at the call site before calling editing_restricted?
  3. Grep custom overrides that call editing_restricted? and update them to current lock types

Example fix

// before
record.editing_restricted?(edit_type_param.to_sym)
// after
edit = edit_type_param.to_sym
raise ArgumentError, 'bad edit type' unless [:all, :any, *MasterCourses::LOCK_TYPES].include?(edit)
record.editing_restricted?(edit)
Defensive patterns

Strategy: validation

Validate before calling

ALLOWED = [:all, :any, *MasterCourses::LOCK_TYPES]
record.editing_restricted?(edit_type) if ALLOWED.include?(edit_type)

Type guard

def editable_restriction_type?(t)
  t == :all || t == :any || MasterCourses::LOCK_TYPES.include?(t)
end

Try / catch

begin
  restricted = record.editing_restricted?(type)
rescue RuntimeError => e
  raise unless e.message == 'invalid edit type'
  restricted = false
end

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/498f6254b9c32ad4. Report an issue: GitHub.

Appendix: source

Thrown at app/models/master_courses/restrictor.rb:138

      end
    end

    def editing_restricted?(edit_type = :all) # edit_type can be :all, :any, or a specific type: :content, :settings, :due_dates, :availability_dates, :points
      return false unless is_child_content?

      restrictions = child_content_restrictions
      return false unless restrictions.present?
      return true if restrictions[:all]

      case edit_type
      when :all
        self.class.base_class.restricted_column_settings.keys.all? { |type| restrictions[type] } # make it possible to only have restrictions on one type
      when :any
        self.class.base_class.restricted_column_settings.keys.any? { |type| restrictions[type] }
      when *MasterCourses::LOCK_TYPES
        !!restrictions[edit_type]
      else
        raise "invalid edit type"
      end
    end

    def skip_restrictions?
      @importing_migration || @skip_downstream_changes || !is_child_content? # don't mark changes on import
    end
  end

  def check_restrictions?
    !new_record?
  end

  def mark_downstream_changes(changed_columns = nil)
    return if skip_restrictions?

    changed_columns ||= saved_changes.keys & self.class.base_class.restricted_column_settings.values.flatten
    state_column = is_a?(Attachment) ? "file_state" : "workflow_state"
    if saved_changes[state_column]&.last == "deleted"

View on GitHub (pinned to 1c9f0bb801)