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
- Remove the sort parameter when querying users outside a course context
- Branch client code on context type and only send sortable fields for courses
- Rescue RequestError (400) and retry without the sort field
- 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
- Only send course-only sort params for course contexts
- Centralize sort-param handling per context type
- Document which sort fields require course scope
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
- Invalid enrollment type: #
- A new_id, '# ', referenced an existing # and the # with #…
- A new_integration_id, '#
- A student referenced a non-existent user #
- A user did not pass validation
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)