{"record":{"id":"cc232fb50876161a","repo":"instructure/canvas-lms","slug":"not-authorized-create-institutional-tag","errorCode":null,"errorMessage":"not authorized","messagePattern":"not authorized","errorType":"exception","errorClass":"GraphQL::ExecutionError","httpStatus":null,"severity":"error","filePath":"app/graphql/mutations/create_institutional_tag.rb","lineNumber":37,"sourceCode":"#\n\n# NOTE: Depends on InstitutionalTag and InstitutionalTagCategory models\n\nmodule Mutations\n  class CreateInstitutionalTag < BaseMutation\n    argument :category_id,\n             ID,\n             required: true,\n             prepare: GraphQLHelpers.relay_or_legacy_id_prepare_func(\"InstitutionalTagCategory\")\n    argument :description, String, required: true\n    argument :name,        String, required: true\n\n    field :institutional_tag, Types::InstitutionalTagType, null: true\n\n    def resolve(input:)\n      root_account = context[:domain_root_account]\n      raise GraphQL::ExecutionError, \"feature flag is disabled\" unless root_account.feature_enabled?(:institutional_tags)\n      raise GraphQL::ExecutionError, \"not authorized\" unless root_account.grants_right?(current_user, session, :manage_institutional_tags_create)\n\n      category = root_account.institutional_tag_categories.where(workflow_state: \"active\").find_by(id: input[:category_id])\n      raise GraphQL::ExecutionError, \"not found\" unless category\n\n      max_tags = DynamicSettings.find(\"institutional_tags\")[\"max_tags_per_category\", failsafe: nil]&.to_i || 50\n      if category.institutional_tags.where(workflow_state: \"active\").count >= max_tags\n        raise GraphQL::ExecutionError, \"category has reached the maximum number of tags\"\n      end\n\n      tag = category.institutional_tags.new(\n        name: input[:name],\n        description: input[:description],\n        root_account:\n      )\n\n      if tag.save\n        { institutional_tag: tag }\n      else","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/graphql/mutations/create_institutional_tag.rb#L19-L55","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Grant the user's role the manage_institutional_tags_create right (Account > Permissions or role override).","Verify the request is authenticated as the intended admin (check context[:session] and current_user).","Confirm the check runs against the correct domain_root_account.","If the right name changed in a recent release, reconcile role overrides with the current permission definition."],"exampleFix":"// before\ngrants_right?(user, session, :manage_institutional_tags_create) # => false\n// after (console)\nrole = root_account.roles.find_by(name: 'AccountAdmin')\nrole.add_permission!(:manage_institutional_tags_create) # or assign user a role with the right","handlingStrategy":"validation","validationCode":"# pre-flight check\nroot_account.grants_right?(user, session, :manage_institutional_tags_create) or\nraise 'user lacks manage_institutional_tags_create'","typeGuard":"def can_manage_institutional_tags?(root_account, user, session)\n  !user.nil? && root_account.grants_right?(user, session, :manage_institutional_tags_create)\nend","tryCatchPattern":"try {\n  await createInstitutionalTag({ variables })\n} catch (e) {\n  if (e.message === 'not authorized') {\n    // prompt for a properly provisioned account / re-authenticate\n  }\n}","preventionTips":["Provision service and integration users with manage_institutional_tags_create explicitly","Re-verify rights after role or permission definition changes","Authenticate the GraphQL request with a session so current_user is set","Add permission-matrix specs for new institutional-tag permissions"],"tags":["graphql","permissions","authorization","canvas"],"backgroundTag":"permission-denied","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"}