instructure/canvas-lms · error · ParameterError

search_type must be one of #

Error message

search_type must be one of #{SEARCH_TYPES}

What it means

UserListV2#initialize in lib/user_list_v.rb raises ParameterError when the search_type argument is not included in SEARCH_TYPES. The class only supports a fixed set of search strategies and fails fast at construction time on any other value.

Solutions

  1. Pass one of the values in UserListV2::SEARCH_TYPES (check the constant for the exact list)
  2. Validate/normalize the search_type parameter before constructing UserListV2
  3. Update the caller after a rename of a search type constant
  4. Rescue ParameterError at the API/controller boundary to return a 400 with the allowed values

Example fix

// before
UserListV2.new(list, search_type: 'email')
// after
UserListV2.new(list, search_type: UserListV2::SEARCH_TYPES.first) # e.g. a valid type like 'cc_path'
Defensive patterns

Strategy: validation

Validate before calling

raise ParameterError unless UserListV2::SEARCH_TYPES.include?(search_type)

Try / catch

begin
  UserListV2.new(list, search_type: params[:search_type])
rescue ParameterError => e
  render json: {error: e.message, allowed: UserListV2::SEARCH_TYPES}, status: :bad_request
end

Prevention

When it happens

Trigger: Calling UserListV2.new(list_in, search_type: ...) with a typo'd or unsupported search_type (anything not in SEARCH_TYPES, e.g. 'emails' instead of 'cc_path'/'unique_id' style values).

Common situations: Tool integrations passing user-supplied search type straight through without whitelisting; refactors renaming search types; typos in constants passed by controllers building user lists.

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/64624afe142b1eaa. Report an issue: GitHub.

Appendix: source

Thrown at lib/user_list_v2.rb:49

  # - only search on particular columns
  # - don't worry about whether we can create users or not: they either exist or they don't

  SEARCH_TYPES = %w[unique_id sis_user_id cc_path].freeze

  def initialize(list_in, root_account: Account.default, search_type: nil, current_user: nil, can_read_sis: false)
    @errors = []
    @addresses = []

    @all_results = []
    @resolved_results = []
    @duplicate_results = []
    @missing_results = []

    @root_account = root_account
    @current_user = current_user
    @can_read_sis = can_read_sis
    unless SEARCH_TYPES.include?(search_type)
      raise ParameterError, "search_type must be one of #{SEARCH_TYPES}"
    end

    parse_list(list_in)

    case search_type
    when "unique_id"
      resolve_by_unique_id
    when "sis_user_id"
      raise "cannot read sis ids" unless @can_read_sis

      resolve_by_sis_user_id
    when "cc_path"
      resolve_by_cc_path
    end
    resolve_duplicates_and_missing
  end

  attr_reader :errors, :addresses, :resolved_results, :duplicate_results, :missing_results

View on GitHub (pinned to 1c9f0bb801)