instructure/canvas-lms · error · InsufficientPermissionsError
Insufficient Permissions
Error message
Insufficient Permissions
What it means
build_entry raises the custom InsufficientPermissionsError when the freshly built DiscussionEntry does not grant :create to the current user (entry.grants_right?). resolve rescues it and converts it to a GraphQL validation error with message "Insufficient Permissions". This is a policy failure, not a data failure: records exist but the user may not post.
Solutions
- Check the topic's locked/available state (locked_for_user, available_from/until) before rendering the reply editor.
- Verify the user's enrollment and that the topic grants :create via the discussionTopic.permissions GraphQL field.
- Unlock the topic or adjust the user's role/permissions if posting should be allowed.
- Hide the reply UI when entryPermissions.create is false so users never hit the error.
Example fix
// before: always show reply box
<ReplyForm topicId={topic.id} />
// after
{topic.permissions.create && <ReplyForm topicId={topic.id} />} Defensive patterns
Strategy: validation
Validate before calling
const canCreate = topic.permissions?.create
if (!canCreate) { disableReplyEditor(); return }
if (topic.lockedForUser || isPast(topic.lockDate)) { showLockedNotice(); return } Type guard
const canPost = (topic) => Boolean(topic?.permissions?.create)
Prevention
- Gate all posting UI on entry/discussion permissions fields.
- Respect locked_until and closed_for_comments state in the client.
- Re-check permissions after enrollment or masquerade changes.
When it happens
Trigger: A student replying to a locked/closed-for-comments topic; posting to an anonymous or read-only discussion without :create rights; a user whose enrollment is concluded or who is not enrolled trying to reply; topic locked until a future date.
Common situations: UI not honoring locked_until / closed_for_comments state; group discussions where the user is not in the group; teachers impersonating or masquerading with reduced rights; account-level discussions with restricted posting roles.
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
- insufficient permission
- insufficient permission
- insufficient permission
- insufficient permission
- Insufficient permission
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/5496856cdd932fef.
Report an issue: GitHub.
Appendix: source
Thrown at app/graphql/mutations/create_discussion_entry.rb:93
obj = { discussion_entry: entry, my_sub_assignment_submissions: [] }
if has_sub_assignment_submissions?(current_user, topic)
checkpoint_submissions = topic.assignment&.sub_assignment_submissions&.active&.where(user_id: current_user)
obj[:my_sub_assignment_submissions] = checkpoint_submissions
end
obj
rescue ActiveRecord::RecordNotFound
raise GraphQL::ExecutionError, "not found"
rescue InsufficientPermissionsError
validation_error(I18n.t("Insufficient Permissions"))
end
def build_entry(association, message, topic, is_anonymous_author)
message = Api::Html::Content.process_incoming(message, host: context[:request].host, port: context[:request].port)
entry = association.build(message:, user: current_user, discussion_topic: topic, is_anonymous_author:)
raise InsufficientPermissionsError unless entry.grants_right?(current_user, session, :create)
entry
end
def has_sub_assignment_submissions?(current_user, topic)
# if group discussion context is not a course, then there will be no assignment nor submissions
return false if topic.context.is_a?(Group) && !topic.context.context.is_a?(Course)
course_id = topic.context.is_a?(Course) ? topic.context.id : topic.context.context.id
# for graded group discussions, .assignment for the root topic and for each child topic is the same
# assignment
topic.assignment&.reload&.has_sub_assignments? && current_user.student_enrollments.where(course_id:).exists?
end
class InsufficientPermissionsError < StandardError; end
end
View on GitHub (pinned to 1c9f0bb801)