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
- Run the service as a user with siteadmin :update rights (e.g. the site admin user created by seeds)
- Grant the user site-admin privileges: add them to the site admin account with admin/update rights
- Verify you are on the default shard where Account.site_admin resolves to the correct account
- 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
- Only enqueue report jobs with a verified siteadmin user
- Check grants_right?(user, :update) on Account.site_admin before invoking
- Verify shard context so Account.site_admin resolves correctly
- Audit service users' permissions after role changes
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
- user doesn't have permission to forward these messages
- assessor and assessee required
- association required
- can only forward one conversation at a time
- can't accept
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)