instructure/canvas-lms · error

Course not found

Error message

Course not found

What it means

In the AutoGradeSubmission GraphQL mutation, resolve raises a plain 'Course not found' RuntimeError when submission.assignment&.course is nil — the assignment is not attached to a course (e.g. standalone/sub-assignment context) or was deleted, so authorization and feature checks cannot proceed.

Solutions

  1. Verify the submission id refers to a submission on a live course assignment
  2. Pre-check in the client: load assignment.course before calling the mutation and surface a friendly error
  3. Restore the deleted course/assignment if it was removed unintentionally
  4. Change the mutation to raise GraphQL::ExecutionError instead of RuntimeError for a cleaner GraphQL error payload

Example fix

# before
raise "Course not found" unless course
# after
raise GraphQL::ExecutionError, "Course not found for assignment" unless course
Defensive patterns

Strategy: validation

Validate before calling

const submission = await canvas.get(`/api/v1/courses/${courseId}/assignments/${assignmentId}/submissions/${userId}`);
if (!submission?.assignment?.course_id) {
  throw new Error('Submission has no course assignment; cannot auto-grade');
}

Type guard

function isCourseSubmission(sub) {
  return sub != null && sub.assignment != null && typeof sub.assignment.course_id === 'number' && sub.assignment.course_id > 0;
}

Try / catch

try {
  await autoGradeSubmission({ submissionId });
} catch (e) {
  if (e.message === 'Course not found') {
    showError('This submission no longer belongs to a course; refresh and retry.');
  }
}

Prevention

When it happens

Trigger: Calling autoGradeSubmission for a submission whose assignment has no course association (assignment belongs to a deleted course, an orphaned assignment, or assignment nil despite earlier checks).

Common situations: Sub-assignments/checkpoint setups where the parent object was deleted; data inconsistencies after course deletion; mutation invoked on an assignment in a non-course context.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/62b579459ad425b7. Report an issue: GitHub.

Appendix: source

Thrown at app/graphql/mutations/auto_grade_submission.rb:40

  argument :submission_id, ID, required: true

  field :error, String, null: true
  field :progress, Types::ProgressType, null: true

  def resolve(input:)
    submission_id = GraphQLHelpers.parse_relay_or_legacy_id(input[:submission_id], "Submission")
    submission = Submission.find(submission_id)

    errors = []
    GraphQLHelpers::AutoGradeEligibilityHelper.validate_assignment(assignment: submission.assignment).each { |i| append_issue_message(errors, i) }
    GraphQLHelpers::AutoGradeEligibilityHelper.validate_submission(submission:).each { |i| append_issue_message(errors, i) }

    if errors.any?
      raise GraphQL::ExecutionError, "Auto-grading failed due to the following issue(s): #{errors.join(", ")}"
    end

    course = submission.assignment&.course
    raise "Course not found" unless course

    unless course.feature_enabled?(:project_lhotse)
      raise GraphQL::ExecutionError, I18n.t("Project Lhotse is not enabled for this course.")
    end

    verify_authorized_action!(course, :manage_grades)

    service = AutoGradeOrchestrationService.new(course:, current_user:)
    progress = service.auto_grade_in_background(submission:)

    { progress: }
  rescue GraphQL::ExecutionError => e
    Rails.logger.error("[AutoGradeSubmission GraphQL ExecutionError] #{e.message}")
    raise e
  rescue => e
    Rails.logger.error("[AutoGradeSubmission ERROR] #{e.message}")
    raise GraphQL::ExecutionError, I18n.t("An unexpected error occurred while grading.")
  end

View on GitHub (pinned to 1c9f0bb801)