{"record":{"id":"1b158f6031abcbaf","repo":"instructure/canvas-lms","slug":"not-authorized-update-institutional-tag","errorCode":null,"errorMessage":"not authorized","messagePattern":"not authorized","errorType":"exception","errorClass":"GraphQL::ExecutionError","httpStatus":null,"severity":"error","filePath":"app/graphql/mutations/update_institutional_tag.rb","lineNumber":41,"sourceCode":"module Mutations\n  class UpdateInstitutionalTag < BaseMutation\n    argument :category_id,\n             ID,\n             required: false,\n             prepare: GraphQLHelpers.relay_or_legacy_id_prepare_func(\"InstitutionalTagCategory\")\n    argument :description, String, required: false\n    argument :id,\n             ID,\n             required: true,\n             prepare: GraphQLHelpers.relay_or_legacy_id_prepare_func(\"InstitutionalTag\")\n    argument :name, String, required: false\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_edit)\n\n      tag = InstitutionalTag.where(root_account_id: root_account.id, workflow_state: \"active\").find_by(id: input[:id])\n      raise GraphQL::ExecutionError, \"not found\" unless tag\n\n      attrs = {}\n      attrs[:name] = input[:name] if input.key?(:name)\n      attrs[:description] = input[:description] if input.key?(:description)\n\n      if input.key?(:category_id)\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        attrs[:category_id] = category.id\n      end\n\n      if tag.update(attrs)\n        { institutional_tag: tag }\n      else","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/graphql/mutations/update_institutional_tag.rb#L23-L59","documentation":"The updateInstitutionalTag mutation requires the acting user to hold the :manage_institutional_tags_edit right on the domain root account. When grants_right? returns false, it raises GraphQL::ExecutionError \"not authorized\" before any tag lookup occurs.","triggerScenarios":"Any updateInstitutionalTag call where the current user is a student/teacher/plain admin lacking the manage_institutional_tags_edit permission, the user's session has expired to an unauthenticated role, or the permission was disabled at the account role level.","commonSituations":"Role permission edits removing the right from custom admin roles; calling the mutation from a background job/script with no user context; users assuming admin status implies this specific granular permission.","solutions":["Grant the user a role with :manage_institutional_tags_edit on the root account (Account > Permissions).","Check the current permission: root_account.grants_right?(user, session, :manage_institutional_tags_edit) in console.","Verify the user session/authentication is valid and current_user is the expected account admin.","Hide the editing UI for users without the permission so the mutation is not invoked."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// check the user's permission before invoking\nconst perms = await fetchMyPermissions(rootAccountId)\nif (!perms.includes('manage_institutional_tags_edit')) throw new Error('user not authorized')","typeGuard":null,"tryCatchPattern":"try {\n  await updateInstitutionalTag(input)\n} catch (e) {\n  if (e.graphQLErrors?.some(g => g.message === 'not authorized')) {\n    showAccessDeniedNotice()\n  } else { throw e }\n}","preventionTips":["Hide institutional tag editing from users lacking manage_institutional_tags_edit.","Audit custom account roles so the permission is explicitly granted where needed.","Use service tokens tied to a permissioned admin user, not anonymous contexts."],"tags":["graphql","authorization","permissions","canvas-lms"],"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"}