{"record":{"id":"09463e06b84fac16","repo":"instructure/canvas-lms","slug":"an-unexpected-error-occurred-while-grading","errorCode":null,"errorMessage":"An unexpected error occurred while grading.","messagePattern":"An unexpected error occurred while grading\\.","errorType":"exception","errorClass":"GraphQL::ExecutionError","httpStatus":null,"severity":"error","filePath":"app/graphql/mutations/auto_grade_submission.rb","lineNumber":57,"sourceCode":"    course = submission.assignment&.course\n    raise \"Course not found\" unless course\n\n    unless course.feature_enabled?(:project_lhotse)\n      raise GraphQL::ExecutionError, I18n.t(\"Project Lhotse is not enabled for this course.\")\n    end\n\n    verify_authorized_action!(course, :manage_grades)\n\n    service = AutoGradeOrchestrationService.new(course:, current_user:)\n    progress = service.auto_grade_in_background(submission:)\n\n    { progress: }\n  rescue GraphQL::ExecutionError => e\n    Rails.logger.error(\"[AutoGradeSubmission GraphQL ExecutionError] #{e.message}\")\n    raise e\n  rescue => e\n    Rails.logger.error(\"[AutoGradeSubmission ERROR] #{e.message}\")\n    raise GraphQL::ExecutionError, I18n.t(\"An unexpected error occurred while grading.\")\n  end\n\n  def append_issue_message(errors, issue)\n    errors << issue[:message] if issue && issue[:level] == \"error\"\n  end\nend\n","sourceCodeStart":39,"sourceCodeEnd":64,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/graphql/mutations/auto_grade_submission.rb#L39-L64","documentation":"AutoGradeSubmission's resolve wraps its grading logic in a catch-all rescue. Any non-GraphQL error raised during the mutation (e.g. inside the AutoGrade service, model callbacks, or I18n/network calls) is logged and re-raised as a GraphQL::ExecutionError with the generic message 'An unexpected error occurred while grading.' This is a deliberately opaque internal-failure guard so no internal details leak to API consumers.","triggerScenarios":"Calling mutation autoGradeSubmission when any standard (non-GraphQL::ExecutionError) exception escapes resolve: AutoGrade service raising, ActiveRecord errors not wrapped as ExecutionError, nil progress target, or any bug in grading callbacks.","commonSituations":"Grading service misconfiguration, feature-flagged AI grading backend unavailable, invalid submission state hitting model validations mid-transaction, or version drift where the service returns nil and downstream code calls a method on it.","solutions":["Check server logs for the '[AutoGradeSubmission ERROR]' line to see the real exception message","Reproduce the grading call in rails console to surface the underlying exception","Confirm the submission/assignment exists and is in a gradable state","If the real cause is expected, rescue it specifically in resolve and return a meaningful GraphQL::ExecutionError"],"exampleFix":"// before\nraise GraphQL::ExecutionError, I18n.t(\"An unexpected error occurred while grading.\")\n// after\nrescue AutoGrade::ServiceUnavailable => e\n  raise GraphQL::ExecutionError, I18n.t(\"Grading service unavailable, try again later.\")","handlingStrategy":"try-catch","validationCode":"// pre-check before calling the mutation\nconst submission = await canvas.get(`/api/v1/courses/${courseId}/assignments/${assignmentId}/submissions/${userId}`)\nif (!submission || submission.workflow_state === 'unsubmitted') throw new Error('nothing to grade')","typeGuard":"function isGradingResult(r) { return r != null && typeof r.progress === 'object' && r.progress != null && r.progress.id != null }","tryCatchPattern":"try {\n  await client.mutate({ mutation: AUTO_GRADE_SUBMISSION, variables: { id } })\n} catch (e) {\n  if (e.message.includes('An unexpected error occurred while grading')) {\n    // check server logs for real cause; surface retry-able UI\n  }\n  throw e\n}","preventionTips":["Always check the '[AutoGradeSubmission ERROR]' log line to diagnose, since the client message is generic","Ensure the submission is in a gradable state before invoking","Keep the AutoGrade backend service and feature flags verified in each environment","Wrap known service failures in specific rescues so they don't fall into the catch-all"],"tags":["graphql","mutation","internal-error","grading"],"backgroundTag":"internal-invariant-violation","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"}