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

e.message (Assignment::MaxGradersReachedError)

Error message

e.message (Assignment::MaxGradersReachedError)

What it means

When a provisional grader submits a rubric assessment on a moderated assignment, the mutation claims a grading slot. Assignment::MaxGradersReachedError (rescued here) means no slots remain for this grader, and its message is surfaced as a GraphQL::ExecutionError.

Solutions

  1. Increase allowed provisional graders for the assignment or remove an inactive provisional grader.
  2. Confirm the current_user is among the intended graders for this moderated assignment.
  3. Retry later once another grader finishes and slots free up; surface the message to the end user.

Example fix

// before
rescue Assignment::MaxGradersReachedError => e
  raise GraphQL::ExecutionError, e.message
// after
rescue Assignment::MaxGradersReachedError => e
  raise GraphQL::ExecutionError, e.message.to_s.presence || 'Maximum number of graders reached for this assignment'
Defensive patterns

Strategy: retry

Validate before calling

const graders = assignment.provisionalGraders?.length ?? 0
if (graders >= assignment.allowedProvisionalGraders) showError('Grader slots full')

Try / catch

try { await saveRubricAssessment(...) } catch (e) { if (e.message.includes('graders')) retryWithBackoff(3) }

Prevention

When it happens

Trigger: Moderated assignment with a limited number of provisional graders already full; a grader outside the allowed set attempts to grade; concurrent grading consumed the last slot between check and claim.

Common situations: Large moderated grading teams configured with fewer slots than graders; retries after failure re-claiming slots.

Related errors


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

Appendix: source

Thrown at app/graphql/mutations/save_rubric_assessment.rb:82

        assessment_type = assessment_details[:assessment_type]

        unless association.user_can_assess_for?(assessor: current_user, assessee: user, assessment_type:)
          raise GraphQL::ExecutionError, "Not authorized to assess user"
        end

        rubric_assessment = association.assess(
          assessor: current_user,
          user:,
          artifact: asset,
          assessment: assessment_details,
          graded_anonymously: input[:graded_anonymously]
        )

        submission.reload
        return { submission:, rubric_assessment:, rubric_association: association }
      end
    rescue Assignment::MaxGradersReachedError => e
      raise GraphQL::ExecutionError, e.message
    rescue Assignment::GradeError
      raise GraphQL::ExecutionError, "Assignment Grade Error"
    end
  rescue ActiveRecord::RecordNotFound => e
    raise GraphQL::ExecutionError, "#{e.model} not found"
  end

  def ensure_adjudication_possible(provisional:, association_object:, grader:, &)
    # Non-assignment association objects crash if they're passed into this
    # controller, since find_asset_for_assessment only exists on assignments.
    # The check here thus serves only to make sure the crash doesn't happen on
    # the call below.
    return yield unless association_object.is_a?(Assignment)

    association_object.ensure_grader_can_adjudicate(
      grader:,
      provisional:,
      occupy_slot: true,

View on GitHub (pinned to 1c9f0bb801)