instructure/canvas-lms · error · GraphQL::ExecutionError
insufficient permission
Error message
insufficient permission
What it means
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.
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.
Example fix
// before
const res = await gql(createLearningOutcomeMutation, { input })
// after
const canCreate = await gql(checkOutcomePermissionQuery, { contextId })
if (!canCreate) throw new UserFacingError('You need outcome-creation rights')
const res = await gql(createLearningOutcomeMutation, { input }) Defensive patterns
Strategy: validation
Validate before calling
const perms = await gql(CONTEXT_PERMISSIONS, { contextId, contextType })
if (!perms.createOutcome) throw new Error('user lacks :create on outcome context') Try / catch
try {
await gql(CREATE_OUTCOME, { input })
} catch (e) {
if (e.message === 'insufficient permission') renderPermissionDenied()
else throw e
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
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/06bf92b115b18539.
Report an issue: GitHub.
Appendix: source
Thrown at app/graphql/mutations/create_learning_outcome.rb:49
record = LearningOutcome.new(context: outcome_group.context, **outcome_input)
record.saving_user = current_user
check_permission(record)
return errors_for(record) unless record.save
outcome_group.add_outcome(record)
{ learning_outcome: record }
end
private
def learning_outcome_group(input)
LearningOutcomeGroup.active.find_by(id: input[:group_id]).tap do |group|
raise GraphQL::ExecutionError, I18n.t("group not found") if group.nil?
end
end
def check_permission(outcome)
raise GraphQL::ExecutionError, I18n.t("insufficient permission") unless outcome.grants_right? current_user, :create
end
end
View on GitHub (pinned to 1c9f0bb801)