instructure/canvas-lms · error · GraphQL::ExecutionError

not authorized

Error message

not authorized

What it means

After the feature-flag check, CreateInstitutionalTag verifies the current user holds the manage_institutional_tags_create right on the root account. If root_account.grants_right? returns false the mutation raises this GraphQL::ExecutionError. It is an explicit authorization gate for creating institutional tags.

Solutions

  1. Grant the user's role the manage_institutional_tags_create right (Account > Permissions or role override).
  2. Verify the request is authenticated as the intended admin (check context[:session] and current_user).
  3. Confirm the check runs against the correct domain_root_account.
  4. If the right name changed in a recent release, reconcile role overrides with the current permission definition.

Example fix

// before
grants_right?(user, session, :manage_institutional_tags_create) # => false
// after (console)
role = root_account.roles.find_by(name: 'AccountAdmin')
role.add_permission!(:manage_institutional_tags_create) # or assign user a role with the right
Defensive patterns

Strategy: validation

Validate before calling

# pre-flight check
root_account.grants_right?(user, session, :manage_institutional_tags_create) or
raise 'user lacks manage_institutional_tags_create'

Type guard

def can_manage_institutional_tags?(root_account, user, session)
  !user.nil? && root_account.grants_right?(user, session, :manage_institutional_tags_create)
end

Try / catch

try {
  await createInstitutionalTag({ variables })
} catch (e) {
  if (e.message === 'not authorized') {
    // prompt for a properly provisioned account / re-authenticate
  }
}

Prevention

When it happens

Trigger: createInstitutionalTag invoked by a user lacking manage_institutional_tags_create on the domain root account — e.g. a plain teacher/admin without the institutional-tag management entitlement, or an unauthenticated/expired-session context where current_user is nil.

Common situations: Calling the mutation with a service token or student token; new custom role without the right granted; the right exists only on a different root account/shard; session missing so grants_right? fails even for admins.

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/cc232fb50876161a. Report an issue: GitHub.

Appendix: source

Thrown at app/graphql/mutations/create_institutional_tag.rb:37

#

# NOTE: Depends on InstitutionalTag and InstitutionalTagCategory models

module Mutations
  class CreateInstitutionalTag < BaseMutation
    argument :category_id,
             ID,
             required: true,
             prepare: GraphQLHelpers.relay_or_legacy_id_prepare_func("InstitutionalTagCategory")
    argument :description, String, required: true
    argument :name,        String, required: true

    field :institutional_tag, Types::InstitutionalTagType, null: true

    def resolve(input:)
      root_account = context[:domain_root_account]
      raise GraphQL::ExecutionError, "feature flag is disabled" unless root_account.feature_enabled?(:institutional_tags)
      raise GraphQL::ExecutionError, "not authorized" unless root_account.grants_right?(current_user, session, :manage_institutional_tags_create)

      category = root_account.institutional_tag_categories.where(workflow_state: "active").find_by(id: input[:category_id])
      raise GraphQL::ExecutionError, "not found" unless category

      max_tags = DynamicSettings.find("institutional_tags")["max_tags_per_category", failsafe: nil]&.to_i || 50
      if category.institutional_tags.where(workflow_state: "active").count >= max_tags
        raise GraphQL::ExecutionError, "category has reached the maximum number of tags"
      end

      tag = category.institutional_tags.new(
        name: input[:name],
        description: input[:description],
        root_account:
      )

      if tag.save
        { institutional_tag: tag }
      else

View on GitHub (pinned to 1c9f0bb801)