instructure/canvas-lms · warning · GraphQL::ExecutionError

Not authorized to delete SubmissionComment

Error message

Not authorized to delete SubmissionComment

What it means

The deleteSubmissionComment mutation raises "Not authorized to delete SubmissionComment" when submission_comment is nil or grants_right?(current_user, :delete) is false. The user either referenced a nonexistent comment or lacks delete rights on it.

Solutions

  1. Confirm the comment exists and is visible to the caller via a SubmissionComment query
  2. Check the user has :delete right on the comment (own ungraded comment or teacher/admin)
  3. Use a teacher/admin token when deleting others' comments
  4. Verify the submission is not yet graded if the deleter is the comment author

Example fix

// before
raise GraphQL::ExecutionError, "Not authorized to delete SubmissionComment"
// after
if submission_comment.nil?
  raise GraphQL::ExecutionError, "SubmissionComment not found"
elsif submission_comment.grants_right?(current_user, :delete)
  submission_comment.destroy
else
  raise GraphQL::ExecutionError, "Not authorized to delete SubmissionComment"
end
Defensive patterns

Strategy: try-catch

Validate before calling

const comment = await query(submissionComment, { id });
if (!comment?.permissions?.delete) throw new Forbidden();

Type guard

function canDeleteComment(c) {
  return c != null && c.permissions?.delete === true;
}

Try / catch

try {
  await client.mutate(DELETE_SUBMISSION_COMMENT, { id });
} catch (e) {
  if (e.message === "Not authorized to delete SubmissionComment") {
    notifyUser("You cannot delete this comment.");
  } else throw e;
}

Prevention

When it happens

Trigger: Calling deleteSubmissionComment with an id the user cannot see (nil result upstream), a student trying to delete their own comment after the submission was graded, a user deleting another student's comment, or a teacher without :delete on the comment.

Common situations: Students attempting to edit/delete comments after grading (Canvas typically locks this), cross-course comment ids, or deleted comments still cached client-side.

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/31f0ec660af85979. Report an issue: GitHub.

Appendix: source

Thrown at app/graphql/mutations/delete_submission_comment.rb:38

class Mutations::DeleteSubmissionComment < Mutations::BaseMutation
  graphql_name "DeleteSubmissionComment"

  argument :submission_comment_id, ID, required: true, prepare: GraphQLHelpers.relay_or_legacy_id_prepare_func("SubmissionComment")

  field :submission_comment, Types::SubmissionCommentType, null: true

  def resolve(input:)
    submission_comment = SubmissionComment.find_by(id: input[:submission_comment_id])

    response = {}
    if submission_comment&.grants_right?(current_user, :delete)
      submission_comment.updating_user = @current_user
      submission_comment.destroy

      response[:submission_comment] = submission_comment
    else
      raise GraphQL::ExecutionError, "Not authorized to delete SubmissionComment"
    end

    response
  end
end

View on GitHub (pinned to 1c9f0bb801)