instructure/canvas-lms · error · ArgumentError

Invalid user

Error message

Invalid user

What it means

PageViews::EnqueueQueryService#call raises ArgumentError when the user argument is not an instance of User. The single-user query service needs user.global_id and the user's shard for root account uuids, so it strictly type-checks the argument before building the async request.

Solutions

  1. Use User.find (raises RecordNotFound) or check the find_by result for nil before calling
  2. Load the User record from the id: User.find(user_id)
  3. Validate user.is_a?(User) in the caller and fail with a clearer message

Example fix

// before
user = User.find_by(id: params[:user_id])
PageViews::EnqueueQueryService.call(start, end, user, format)
// after
user = User.find(params[:user_id])
PageViews::EnqueueQueryService.call(start, end, user, format)
Defensive patterns

Strategy: type-guard

Validate before calling

raise ArgumentError, 'user must be a User' unless user.is_a?(User)

Type guard

def loaded_user?(value)
  value.is_a?(User)
end

Try / catch

begin
  PageViews::EnqueueQueryService.call(start_date, end_date, user, format)
rescue ArgumentError => e
  Rails.logger.warn("page views enqueue rejected: #{e.message}")
end

Prevention

When it happens

Trigger: Calling call(start_date, end_date, user, format) with a user id, a nil (e.g. User.find_by found nothing), a hash, or another model instance.

Common situations: Forwarding the result of User.find_by(email: ...) which can be nil; passing an id string from a controller param; passing a cached serialized user hash.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at app/services/page_views/enqueue_query_service.rb:23

#
# This file is part of Canvas.
#
# Canvas is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the Free
# Software Foundation, version 3 of the License.
#
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.

module PageViews
  class EnqueueQueryService < PageViews::ServiceBase
    def call(start_date, end_date, user, format)
      raise ArgumentError, "Invalid user" unless user.is_a?(User)

      uri = @configuration.uri.merge("/api/v5/pageviews/query")
      start_date = parse_date_only(start_date) unless start_date.is_a?(Date)
      end_date = parse_date_only(end_date) unless end_date.is_a?(Date)
      request = Common::AsyncQueryRequest.new(start_date:, end_date:, user_id: user.global_id, root_account_uuids: cached_root_account_uuids_for(user:), 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

View on GitHub (pinned to 1c9f0bb801)