instructure/canvas-lms · error · GraphQL::ExecutionError
Insufficient permissions
Error message
Insufficient permissions
What it means
CreateLearningOutcomeGroup#check_user_permissions raises 'Insufficient permissions' unless can_manage_outcomes. can_manage_outcomes checks @outcome_group.context.grants_right?(current_user, session, :manage_outcomes); when the group has no context it falls back to site-admin manage rights. So the caller must hold :manage_outcomes in the group's context.
Solutions
- Run the mutation as a user with :manage_outcomes on the target group's context (usually an account admin).
- Check RoleOverride/permission settings for the user's role in that account and enable 'Manage Learning Outcomes' if appropriate.
- Target a group whose context matches where the user has rights (course group for teachers).
- Pre-flight the permission via GraphQL permissions fields on the context before calling the mutation.
Example fix
// before
await gql(createLearningOutcomeGroupMutation, { input })
// after
const perms = await gql(groupPermissionsQuery, { groupId })
if (!perms.manageOutcomes) showNoPermissionToast()
else await gql(createLearningOutcomeGroupMutation, { input }) Defensive patterns
Strategy: validation
Validate before calling
const perms = await gql(GROUP_MANAGE_PERMS, { groupId })
if (!perms.manageOutcomes) throw new Error('requires manage_outcomes on the group context') Try / catch
try {
await gql(CREATE_OUTCOME_GROUP, { input })
} catch (e) {
if (e.message === 'Insufficient permissions') showNoManageOutcomesNotice()
else throw e
} Prevention
- Expose the manageOutcomes permission field in your UI gate.
- For course groups confirm the account allows teacher-level outcome management.
- Detect role changes (token reissue) and re-check permissions per session.
When it happens
Trigger: Calling createLearningOutcomeGroup as a teacher in a course where the account restricts outcome management to admins; a sub-account admin operating on a group owned by the root account; unauthenticated requests (context grants nothing).
Common situations: Account-level 'manage outcomes' feature flag or role override turned off for the user's role; writing to a root-account group from a course-scoped tool; using a token that lost its admin role after rotation.
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/cc1b0dc617cdba6c.
Report an issue: GitHub.
Appendix: source
Thrown at app/graphql/mutations/create_learning_outcome_group.rb:54
@child_outcome_group = @outcome_group.child_outcome_groups.build(attributes(input))
@child_outcome_group.saving_user = current_user
if @child_outcome_group.save
{ learning_outcome_group: @child_outcome_group }
else
errors_for(@child_outcome_group)
end
end
private
def get_group(id)
LearningOutcomeGroup.active.find_by(id:).tap do |group|
raise GraphQL::ExecutionError, I18n.t("Group not found") unless group
end
end
def check_user_permissions
raise GraphQL::ExecutionError, I18n.t("Insufficient permissions") unless can_manage_outcomes
end
def can_manage_outcomes
if @outcome_group.context
@outcome_group.context.grants_right?(current_user, session, :manage_outcomes)
else
Account.site_admin.grants_right?(current_user, session, :manage_global_outcomes)
end
end
def attributes(input)
input.to_h.slice(:title, :description, :vendor_guid)
end
end
View on GitHub (pinned to 1c9f0bb801)