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

Enrollment invitation not found

Error message

Enrollment invitation not found

What it means

Raised when no Enrollment record matches the supplied enrollment_uuid. The mutation looks up Enrollment.where(uuid: input[:enrollment_uuid]).first and raises this error when the lookup returns nil, so the invitation cannot be rejected.

Solutions

  1. Verify the uuid corresponds to an existing Enrollment via Enrollment.where(uuid: ...).exists?
  2. Re-send/refresh the invitation link to get the current enrollment uuid
  3. Handle the already-processed case in the UI instead of re-invoking the mutation
  4. Confirm you are hitting the correct Canvas environment/shard

Example fix

// before
rejectEnrollmentInvitation(courseUuid)
// after
rejectEnrollmentInvitation(enrollmentUuid) // Enrollment.find_by(uuid: enrollmentUuid)&.uuid
Defensive patterns

Strategy: validation

Validate before calling

const enrollment = await fetchEnrollmentByUuid(uuid)
if (!enrollment) show('Invitation no longer valid')

Type guard

function isEnrollment(e) { return e != null && typeof e.uuid === 'string' && e.workflowState != null }

Try / catch

try {
  await rejectEnrollmentInvitation({ enrollmentUuid })
} catch (e) {
  if (e.message.includes('Enrollment invitation not found')) {
    show('This invitation has expired or was already processed'); refetchState()
  } else throw e
}

Prevention

When it happens

Trigger: Passing a UUID that is not an enrollment uuid (e.g. the course uuid or a user uuid); the enrollment was already accepted/rejected/deleted and purged; typo or truncated uuid; querying on the wrong shard/root account.

Common situations: Stale email links after the enrollment was re-created (regenerated uuid); user clicks 'decline' twice; uuid copied from a different environment (test vs production).

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at app/graphql/mutations/reject_enrollment_invitation.rb:33

# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#

module Mutations
  class RejectEnrollmentInvitation < BaseMutation
    argument :enrollment_uuid, String, required: true

    field :enrollment, Types::EnrollmentType, null: true
    field :success, Boolean, null: false

    def resolve(input:, **)
      user = context[:current_user]
      raise GraphQL::ExecutionError, I18n.t("Must be logged in") unless user

      enrollment = Enrollment.where(uuid: input[:enrollment_uuid]).first
      raise GraphQL::ExecutionError, I18n.t("Enrollment invitation not found") unless enrollment

      # Verify the enrollment belongs to the current user
      raise GraphQL::ExecutionError, I18n.t("Unauthorized") unless enrollment.user == user

      # Verify the enrollment is in invited state
      raise GraphQL::ExecutionError, I18n.t("Enrollment is not in invited state") unless enrollment.invited?

      begin
        if enrollment.reject
          {
            enrollment:,
            success: true
          }
        else
          {
            enrollment: nil,
            success: false,
            errors: [{ message: I18n.t("Failed to reject enrollment invitation") }]

View on GitHub (pinned to 1c9f0bb801)