{"record":{"id":"982463c41afa50c7","repo":"instructure/canvas-lms","slug":"users-cannot-be-empty","errorCode":null,"errorMessage":"users cannot be empty","messagePattern":"users cannot be empty","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"app/services/page_views/enqueue_batch_query_service.rb","lineNumber":60,"sourceCode":"      )\n      request.validate!\n\n      CanvasHttp.post(\n        uri.to_s,\n        request_headers,\n        content_type: \"application/json\",\n        body: request.to_json\n      ) do |response|\n        handle_generic_errors(response) unless response.code.to_i == 201\n        return response.header[\"Location\"].split(\"/\").last\n      end\n    end\n\n    private\n\n    def validate_users!(users)\n      raise ArgumentError, \"users must be an array\" unless users.is_a?(Array)\n      raise ArgumentError, \"users cannot be empty\" if users.empty?\n\n      raise ArgumentError, \"all elements must be User objects\" unless users.all?(User)\n    end\n\n    def parse_date_only(date_string)\n      raise ArgumentError, \"Date must be in YYYY-MM-DD format\" unless date_string.match?(/\\A\\d{4}-\\d{2}-\\d{2}\\z/)\n\n      Date.parse(date_string)\n    end\n\n    def collect_root_account_uuids(users)\n      users.flat_map do |user|\n        user.shard.activate do\n          user.root_account_ids.map do |id|\n            Account.find_cached(id).uuid\n          end\n        end\n      end.uniq","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/services/page_views/enqueue_batch_query_service.rb#L42-L78","documentation":"PageViews::EnqueueBatchQueryService#validate_users! raises ArgumentError when the users array is empty. An empty batch would produce a pointless or invalid async query request, so the service rejects it up front. Callers must supply at least one User object.","triggerScenarios":"Calling PageViews::EnqueueBatchQueryService.call with users = [].","commonSituations":"An upstream query/scope returned no users (e.g. no enrollments match) and the empty result was forwarded directly; filtering removed all users before the call.","solutions":["Check users.any? before calling and skip or handle the no-users case","Use users.compact.presence to filter nils and detect emptiness","Return early in the caller when the user list is empty"],"exampleFix":"// before\nservice.call(start_date, end_date, users, format)\n// after\nif users.any?\n  service.call(start_date, end_date, users, format)\nelse\n  Rails.logger.info('no users to enqueue page views for')\nend","handlingStrategy":"validation","validationCode":"raise ArgumentError, 'no users' if users.nil? || users.empty?\nusers = users.compact","typeGuard":"def nonempty_user_array?(value)\n  value.is_a?(Array) && value.any? && value.all?(User)\nend","tryCatchPattern":"begin\n  service.call(start_date, end_date, users, format)\nrescue ArgumentError => e\n  Rails.logger.info(\"skipping page view batch: #{e.message}\")\nend","preventionTips":["Guard with users.any? before enqueueing","Treat empty user sets as a normal no-op, not an error path","Compact and uniq user collections before batching","Test the empty-scope case in specs"],"tags":["ruby","argument-validation","empty-collection"],"backgroundTag":"empty-required-field","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}