instructure/canvas-lms · error · RequestError

Sorting by # is only available within a course context

Error message

Sorting by #{field} is only available within a course context

What it means

UserSearch.raise_context_error in lib/user_search.rb:475 raises RequestError (400) when a sort field is requested in a non-course context. Called by order_scope, it enforces that certain sortable fields only make sense where course-scoped enrollment data exists.

Solutions

  1. Remove the sort parameter when querying users outside a course context
  2. Branch client code on context type and only send sortable fields for courses
  3. Rescue RequestError (400) and retry without the sort field
  4. Use a context-appropriate default ordering for account/group user lists

Example fix

// before
GET /api/v1/accounts/1/users?sort=surname
// after
GET /api/v1/accounts/1/users # no sort param outside course context
Defensive patterns

Strategy: validation

Validate before calling

raise RequestError.new('sort not allowed here', 400) unless context.is_a?(Course)

Try / catch

begin
  UserSearch.for_user_in_context(term, context, user, session, sort: field)
rescue RequestError => e
  retry_without_sort or render json: {error: e.message}, status: 400
end

Prevention

When it happens

Trigger: Calling the user search/list API with a sort parameter (e.g. sortable_name/surname style course-only fields) on an account or group context where order_scope detects the context is not a Course.

Common situations: Reusing a course users-endpoint client against an account users endpoint with the same sort params; UI code copied from course roster to account user list; generic API wrappers always sending a sort field.

Understand the failure class

Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at lib/user_search.rb:475

      scope
    end

    def email_sql(users_scope, params)
      users_scope.select("users.*, MAX(pseudonyms.current_login_at) as last_login")
                 .joins(:communication_channels)
                 .joins("LEFT JOIN #{Pseudonym.quoted_table_name} ON pseudonyms.user_id = users.id
          AND pseudonyms.account_id = #{User.connection.quote(params[:account].id_for_database)}
          #{"AND pseudonyms.workflow_state = 'active'" unless @include_deleted_users}")
                 .where(communication_channels: { workflow_state: ["active", "unconfirmed"], path_type: params[:path_type] })
                 .where(like_condition("communication_channels.path"), pattern: params[:pattern])
    end

    def wildcard_pattern(value, **)
      ActiveRecord::Base.wildcard_pattern(value, **)
    end

    def raise_context_error(field)
      raise RequestError.new("Sorting by #{field} is only available within a course context", 400)
    end
  end
end

View on GitHub (pinned to 1c9f0bb801)