{"record":{"id":"241415461284a6bd","repo":"instructure/canvas-lms","slug":"insufficient-permission-delete-outcome-proficiency","errorCode":null,"errorMessage":"insufficient permission","messagePattern":"insufficient permission","errorType":"exception","errorClass":"GraphQL::ExecutionError","httpStatus":null,"severity":"warning","filePath":"app/graphql/mutations/delete_outcome_proficiency.rb","lineNumber":38,"sourceCode":"\nclass Mutations::DeleteOutcomeProficiency < Mutations::BaseMutation\n  graphql_name \"DeleteOutcomeProficiency\"\n\n  # input arguments\n  argument :id, ID, required: true\n\n  # the return data if the delete is successful\n  field :outcome_proficiency_id, ID, null: false\n\n  def self.outcome_proficiency_id_log_entry(_entry, context)\n    context[:deleted_models][:outcome_proficiency].context\n  end\n\n  def resolve(input:)\n    record_id = GraphQLHelpers.parse_relay_or_legacy_id(input[:id], \"OutcomeProficiency\")\n    record = OutcomeProficiency.active.find_by(id: record_id)\n    raise GraphQL::ExecutionError, \"Unable to find OutcomeProficiency\" if record.nil?\n    raise GraphQL::ExecutionError, \"insufficient permission\" unless record.context.grants_right? current_user, :manage_proficiency_scales\n\n    context[:deleted_models][:outcome_proficiency] = record\n    record.destroy\n    { outcome_proficiency_id: record.id }\n  end\nend\n","sourceCodeStart":20,"sourceCodeEnd":45,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/graphql/mutations/delete_outcome_proficiency.rb#L20-L45","documentation":"The deleteOutcomeProficiency mutation raises \"insufficient permission\" when the proficiency's context does not grant current_user the :manage_proficiency_scales right. The record exists and is active, but the user cannot modify proficiency scales in that context.","triggerScenarios":"Calling deleteOutcomeProficiency with a valid id while lacking manage_proficiency_scales on record.context — e.g. a teacher attempting account-level proficiency deletion or a sub-account admin on a root-account setting.","commonSituations":"Non-admin tokens, admins scoped to a different account than the record's context, or role overrides not applied to the caller's enrollment.","solutions":["Grant :manage_proficiency_scales to the user's role in the record's context","Authenticate as an account admin with outcome management rights","Verify the proficiency belongs to an account you administer","Check the account permission matrix for role overrides"],"exampleFix":"// before\nrecord.destroy\n// after\nunless record.context.grants_right?(current_user, :manage_proficiency_scales)\n  raise GraphQL::ExecutionError, \"insufficient permission\"\nend\nrecord.destroy","handlingStrategy":"validation","validationCode":"const perms = await query(contextPermissions, { contextId: record.contextId });\nif (!perms?.manageProficiencyScales) throw new Forbidden();","typeGuard":"function canManageScales(perms) {\n  return perms?.manageProficiencyScales === true;\n}","tryCatchPattern":"try {\n  await client.mutate(DELETE_OUTCOME_PROFICIENCY, { id });\n} catch (e) {\n  if (e.message === \"insufficient permission\") {\n    showPermissionHelp(\"manage_proficiency_scales\");\n  } else throw e;\n}","preventionTips":["Gate delete UI on manage_proficiency_scales permission fields","Use tokens for users with outcome scale management rights","Check sub-account vs root-account context of the record","Audit role overrides before running bulk scripts"],"tags":["graphql","authorization","permissions","outcomes"],"backgroundTag":"insufficient-permissions","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"}