instructure/canvas-lms · error · ArgumentError
users must be an array
Error message
users must be an array
What it means
PageViews::EnqueueBatchQueryService#validate_users! raises ArgumentError when the users argument passed to call is not an Array. The service batches page view queries for many users, so it requires an array to iterate over. Any non-array value (nil, a single User, a relation) fails this check immediately before any HTTP work happens.
Solutions
- Wrap a single user in an array: [user]
- Convert ActiveRecord relations with .to_a before calling
- Load User objects from ids: User.where(id: ids).to_a (must be User instances, not ids)
- Add a guard in the caller to skip or raise a clearer error when users is nil
Example fix
// before PageViews::EnqueueBatchQueryService.call(start_date, end_date, user, format) // after PageViews::EnqueueBatchQueryService.call(start_date, end_date, [user], format)
Defensive patterns
Strategy: type-guard
Validate before calling
raise ArgumentError, 'users must be an array of User' unless users.is_a?(Array) && users.all?(User) && users.any?
Type guard
def user_array?(value) value.is_a?(Array) && value.all?(User) end
Try / catch
begin
PageViews::EnqueueBatchQueryService.call(start_date, end_date, users, format)
rescue ArgumentError => e
Rails.logger.warn("page views batch enqueue rejected: #{e.message}")
end Prevention
- Always pass arrays of loaded User records, not ids or relations
- Use .to_a on ActiveRecord relations before calling
- Compact nils out of user collections
- Write a spec asserting ArgumentError for nil/single-user/empty inputs
When it happens
Trigger: Calling PageViews::EnqueueBatchQueryService.call with users = nil, a single User object, an ActiveRecord relation, a hash, or any other non-Array value.
Common situations: Passing one User instead of wrapping it in an array; passing user_ids integers instead of User objects; forgetting that scope results are relations not arrays (e.g. User.where(...)); a nil from an earlier lookup being forwarded.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- all elements must be User objects
- Date must be in YYYY-MM-DD format
- Date must be in YYYY-MM-DD format
- invalid request
- Invalid URI in pv5 config: #
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/90c133616dc05bd4.
Report an issue: GitHub.
Appendix: source
Thrown at app/services/page_views/enqueue_batch_query_service.rb:59
format:
)
request.validate!
CanvasHttp.post(
uri.to_s,
request_headers,
content_type: "application/json",
body: request.to_json
) do |response|
handle_generic_errors(response) unless response.code.to_i == 201
return response.header["Location"].split("/").last
end
end
private
def validate_users!(users)
raise ArgumentError, "users must be an array" unless users.is_a?(Array)
raise ArgumentError, "users cannot be empty" if users.empty?
raise ArgumentError, "all elements must be User objects" unless users.all?(User)
end
def parse_date_only(date_string)
raise ArgumentError, "Date must be in YYYY-MM-DD format" unless date_string.match?(/\A\d{4}-\d{2}-\d{2}\z/)
Date.parse(date_string)
end
def collect_root_account_uuids(users)
users.flat_map do |user|
user.shard.activate do
user.root_account_ids.map do |id|
Account.find_cached(id).uuid
end
endView on GitHub (pinned to 1c9f0bb801)