instructure/canvas-lms · error · GraphQL::ExecutionError
insufficient permission
Error message
insufficient permission
What it means
ensure_destroyed checks `@working_assignment.grants_right?(current_user, :delete)` unconditionally before destroying an assignment (deleteAssignment mutation). If the caller lacks :delete on the assignment, it raises 'insufficient permission' even if the assignment is already deleted.
Solutions
- Grant the user :delete right (e.g., teacher/enrollment with manage assignments permission) before calling deleteAssignment.
- Verify with `assignment.grants_right?(user, :delete)` in console before invoking.
- Check you're authenticated as the intended user (token owner).
- If testing, enroll a teacher or stub grants_right? accordingly.
Example fix
// before
mutation { deleteAssignment(input: { id }) } # as read-only user
// after: ensure caller can delete
user.enroll(course, 'TeacherEnrollment').accept! # or verify
assignment.grants_right?(user, :delete) # true before calling mutation Defensive patterns
Strategy: validation
Validate before calling
if (!assignment.permissions.delete) throw new Error('cannot delete assignment')
Try / catch
try {
await deleteAssignment({ id })
} catch (e) {
if (e.message === 'insufficient permission') showNoPermissionUi()
} Prevention
- Hide delete actions when permissions.delete is false
- Check enrollment/role before API calls
- Re-check permissions after role changes
When it happens
Trigger: Calling deleteAssignment as a user without delete rights on the assignment's course (e.g., teacher where course settings require manage rights, or a student); current_user nil due to unauthenticated token; permission check fails because the assignment belongs to a different course than assumed.
Common situations: Custom roles with delete withheld; API token scoped to a user with read-only access; sub-account admin without course-level delete; automation tokens whose user lost permissions after role changes.
Understand the failure class
Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.
Related errors
- insufficient permission
- insufficient permission
- Insufficient permissions
- invalid context for group
- not authorized
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/390c21588d5c35ca.
Report an issue: GitHub.
Appendix: source
Thrown at app/graphql/mutations/assignment_base.rb:308
# now remove all _tags_ that are not required
(current_module_ids - required_module_ids).to_set.each do |module_id_to_remove|
# assignments can be part of multiple modules, so we have to search through all the tags
# and if context_module_id is the module to remove, then we need to delete the tag
content_tags.each do |tag|
if tag.context_module_id == module_id_to_remove
tag.destroy
end
end
end
# we need to reload the assignment so things get returned correctly
@working_assignment.reload
end
def ensure_destroyed
# check for permissions no matter what
raise GraphQL::ExecutionError, "insufficient permission" unless @working_assignment.grants_right? current_user, :delete
# if we are already destroyed, then dont do anything
return if @working_assignment.workflow_state == "deleted"
# actually destroy now.
SubmissionLifecycleManager.with_executing_user(@current_user) do
@working_assignment.destroy
end
end
def ensure_restored
# if we are already not destroyed, then dont do anything
return if @working_assignment.workflow_state != "deleted"
raise GraphQL::ExecutionError, "insufficient permission" unless @working_assignment.grants_right? current_user, :delete
@working_assignment.restore
end
View on GitHub (pinned to 1c9f0bb801)