instructure/canvas-lms · error · NonSiteAdminError

Must be a siteadmin user!

Error message

Must be a siteadmin user!

What it means

NonSiteAdminError raised by SiteAdminReportingService#call when the invoking user does not have :update rights on the site-admin account. This service generates site-wide reports and is intentionally restricted to Canvas site administrators.

Solutions

  1. Run the service as a user with siteadmin :update rights (e.g. the site admin user created by seeds)
  2. Grant the user site-admin privileges: add them to the site admin account with admin/update rights
  3. Verify you are on the default shard where Account.site_admin resolves to the correct account
  4. Check the user/account setup in a dev environment (rails console: Account.site_admin.grants_right?(user, :update))

Example fix

// before
SiteAdminReportingService.new(user: current_user, source_name: 'grades').call
// after
admin = Account.site_admin.users.find_by(name: 'Site Admin')
raise 'must run as siteadmin' unless Account.site_admin.grants_right?(admin, :update)
SiteAdminReportingService.new(user: admin, source_name: 'grades').call
Defensive patterns

Strategy: validation

Validate before calling

unless Account.site_admin.grants_right?(user, :update)
  raise ArgumentError, 'SiteAdminReportingService requires a siteadmin user'
end

Type guard

null

Try / catch

begin
  SiteAdminReportingService.new(user:, source_name:).call
rescue NonSiteAdminError
  # reject the request with 403 or reroute to a privileged job
end

Prevention

When it happens

Trigger: Calling SiteAdminReportingService.new(user:, ...).call (or the wrapping job) with a user whose Account.site_admin grants do not include :update — i.e. any non-siteadmin user.

Common situations: Running a report rake task/console command as a regular admin instead of a siteadmin; misconfigured shard (site admin account on a different shard); automated jobs whose service user lost siteadmin rights; local dev without seed_admin data.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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

Appendix: source

Thrown at app/services/site_admin_reporting_service.rb:57

  MAX_BACKTRACE_LINES = 1_000

  attr_reader :user,
              :source_name,
              :custom_name,
              :block

  def initialize(user:, source_name:, custom_name: nil, &block)
    super()
    raise NoBlockError, "Must provide a block!" unless block_given?

    @user = user
    @source_name = source_name
    @custom_name = custom_name
    @block = block
  end

  def call
    raise NonSiteAdminError, "Must be a siteadmin user!" unless Account.site_admin.grants_right?(user, :update)

    begin
      Tempfile.create do |file|
        create_report(file)
        file.rewind
        create_attachment(file)
      end
    rescue => e
      save_error_to_attachment(e)
    end
  end

  private

  # Creates a report. To be implemented in subclasses. The block attribute should
  # be used to generate the content of the report.
  # @param file [File] The file to write the report content to.
  # Do not close this file, as it will be closed by the caller.

View on GitHub (pinned to 1c9f0bb801)