{"record":{"id":"3325e58b85f95986","repo":"instructure/canvas-lms","slug":"not-authorized-to-update-submissioncomment","errorCode":null,"errorMessage":"Not authorized to update SubmissionComment","messagePattern":"Not authorized to update SubmissionComment","errorType":"exception","errorClass":"GraphQL::ExecutionError","httpStatus":null,"severity":"error","filePath":"app/graphql/mutations/post_draft_submission_comment.rb","lineNumber":36,"sourceCode":"# with this program. If not, see <http://www.gnu.org/licenses/>.\n#\n\nclass Mutations::PostDraftSubmissionComment < Mutations::BaseMutation\n  graphql_name \"PostDraftSubmissionComment\"\n\n  argument :submission_comment_id, ID, required: true\n\n  field :submission_comment, Types::SubmissionCommentType, null: true\n  def resolve(input:)\n    submission_comment = SubmissionComment.find(input[:submission_comment_id])\n\n    response = {}\n    if submission_comment.grants_right?(current_user, :update)\n      submission_comment.reload unless submission_comment.update(draft: false)\n\n      response[:submission_comment] = submission_comment\n    else\n      raise GraphQL::ExecutionError, \"Not authorized to update SubmissionComment\"\n    end\n\n    response\n  end\nend\n","sourceCodeStart":18,"sourceCodeEnd":42,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/graphql/mutations/post_draft_submission_comment.rb#L18-L42","documentation":"Raised in the PostDraftSubmissionComment mutation when the current user lacks the :update right on the submission comment. Canvas gates comment editing/creation via grants_right?; only the comment's author (or an admin with appropriate rights) may publish a draft comment.","triggerScenarios":"Calling mutation postDraftSubmissionComment with a submission comment id owned by another user, or as a student trying to publish a teacher's draft comment; session/token user differs from the comment author.","commonSituations":"Impersonation/masquerade edge cases; using an old comment id after grading permissions changed; acting as a non-author grader (e.g. TA without edit rights); copying another user's comment id from the network tab.","solutions":["Confirm the current user is the author of the submission comment (submission_comment.author_id == current_user.id)","Check the user's enrollment/role grants :update on the comment (grants_right?(user, :update))","Use a valid masquerade/admin session only if policy permits","Fetch the comment via the API as the intended user to verify access before calling the mutation"],"exampleFix":"// before\npostDraftSubmissionComment(commentId) // called as non-author\n// after\nif (comment.authorId === currentUser.id) {\n  postDraftSubmissionComment(commentId)\n}","handlingStrategy":"validation","validationCode":"const canUpdate = comment.authorId === currentUser.id || currentUser.admin\nif (!canUpdate) disablePublishAction()","typeGuard":"function canPublishComment(comment, user) {\n  return Boolean(user) && (comment.authorId === user.id || user.permissions?.includes('manage_grades'))\n}","tryCatchPattern":"try {\n  await postDraftSubmissionComment({ id })\n} catch (e) {\n  if (e.message.includes('Not authorized')) notify('Only the comment author can publish this draft')\n  else throw e\n}","preventionTips":["Check grants_right?(user, :update) server-side before rendering edit UI","Never attempt to publish another user's draft comment","Refresh permissions after role changes","Verify the active session/token belongs to the comment author"],"tags":["graphql","authorization","submission-comments"],"backgroundTag":"permission-denied","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}