{"record":{"id":"06bf92b115b18539","repo":"instructure/canvas-lms","slug":"insufficient-permission-create-learning-outcome","errorCode":null,"errorMessage":"insufficient permission","messagePattern":"insufficient permission","errorType":"exception","errorClass":"GraphQL::ExecutionError","httpStatus":null,"severity":"error","filePath":"app/graphql/mutations/create_learning_outcome.rb","lineNumber":49,"sourceCode":"    record = LearningOutcome.new(context: outcome_group.context, **outcome_input)\n    record.saving_user = current_user\n    check_permission(record)\n    return errors_for(record) unless record.save\n\n    outcome_group.add_outcome(record)\n    { learning_outcome: record }\n  end\n\n  private\n\n  def learning_outcome_group(input)\n    LearningOutcomeGroup.active.find_by(id: input[:group_id]).tap do |group|\n      raise GraphQL::ExecutionError, I18n.t(\"group not found\") if group.nil?\n    end\n  end\n\n  def check_permission(outcome)\n    raise GraphQL::ExecutionError, I18n.t(\"insufficient permission\") unless outcome.grants_right? current_user, :create\n  end\nend\n","sourceCodeStart":31,"sourceCodeEnd":52,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/graphql/mutations/create_learning_outcome.rb#L31-L52","documentation":"CreateLearningOutcome#check_permission raises 'insufficient permission' when outcome.grants_right?(current_user, :create) is false. The outcome is built in the target group's context, so the caller must have the :create right (typically manage-outcomes related) in that course/account.","triggerScenarios":"Calling createLearningOutcome as a user without :create rights on the outcome's context — e.g. a student, a teacher in a course where outcome management is account-level only, or an admin on a sub-account without outcome permissions.","commonSituations":"Autonomous agents using a teacher token when outcomes are restricted to account admins; role overrides removed :create for teachers; cross-account group where the user has rights in one account but not the group's.","solutions":["Use a token/user with :create rights in the outcome group's context (account admin with manage outcomes, or permissive course role).","Check the context's role overrides for the user's role to confirm :create outcome rights.","Pick a group in a context where the user does have permission.","Catch GraphQL errors with message 'insufficient permission' client-side and surface a permission UI state."],"exampleFix":"// before\nconst res = await gql(createLearningOutcomeMutation, { input })\n// after\nconst canCreate = await gql(checkOutcomePermissionQuery, { contextId })\nif (!canCreate) throw new UserFacingError('You need outcome-creation rights')\nconst res = await gql(createLearningOutcomeMutation, { input })","handlingStrategy":"validation","validationCode":"const perms = await gql(CONTEXT_PERMISSIONS, { contextId, contextType })\nif (!perms.createOutcome) throw new Error('user lacks :create on outcome context')","typeGuard":null,"tryCatchPattern":"try {\n  await gql(CREATE_OUTCOME, { input })\n} catch (e) {\n  if (e.message === 'insufficient permission') renderPermissionDenied()\n  else throw e\n}","preventionTips":["Check per-context outcome permissions in the UI before enabling create flows.","Remember course-level rights depend on account role overrides.","Use a token whose user actually holds outcome-management rights in the target context."],"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"}