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

not found

Error message

not found

What it means

CreateSubmission#resolve wraps assignment.submit_homework in a rescue of ActiveRecord::RecordNotFound, re-raised as 'not found'. submit_homework internally finds the assignment/attempt context, so an unknown assignment ID (or an ID the user may not see) triggers this before submission validation.

Solutions

  1. Re-fetch the assignment via GraphQL to confirm it exists and is published for this user.
  2. Ensure the ID belongs to the current course/shard and hasn't been deleted.
  3. Submit as an enrolled student with visibility of the assignment (hidden records raise not-found).
  4. Catch 'not found' in the client and refresh the assignment list before retrying.

Example fix

// before
await gql(createSubmissionMutation, { input: { assignmentId: cachedId, ... } })
// after
const a = await gql(getAssignment, { id: cachedId })
if (!a) throw new Error('Assignment gone; refresh')
await gql(createSubmissionMutation, { input: { assignmentId: a._id, ... } })
Defensive patterns

Strategy: validation

Validate before calling

const assignment = await gql(GET_ASSIGNMENT, { id: assignmentId })
if (!assignment || assignment.state !== 'published') throw new Error('assignment missing or unpublished')

Type guard

function isSubmittableAssignment(a) { return a != null && a.state === 'published' && !a.lockedForUser }

Try / catch

try {
  await gql(CREATE_SUBMISSION, { input })
} catch (e) {
  if (e.message === 'not found') { await refreshAssignments(); notifyAssignmentGone() }
  else throw e
}

Prevention

When it happens

Trigger: Calling createSubmission with an assignmentId that doesn't exist, was deleted, lives on another shard, or is invisible to the submitting user; submitting to an unpublished assignment via a stale ID.

Common situations: Cached assignment IDs in an LTI tool after course copy; submitting to an assignment that was unpublished/deleted; cross-environment ID reuse between beta and 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/5ed7b0f3cd1188ac. Report an issue: GitHub.

Appendix: source

Thrown at app/graphql/mutations/create_submission.rb:169

          ),
          attribute: "file_ids"
        )
      end

      upload_errors =
        validate_online_upload(assignment, attachments, is_proxy: !!input[:student_id])
      return upload_errors if upload_errors

      submission_params[:attachments] =
        Attachment.copy_attachments_to_submissions_folder(context, attachments)
    when "online_url"
      submission_params[:url] = input[:url]
    end

    submission = assignment.submit_homework(current_user, submission_params)
    { submission: }
  rescue ActiveRecord::RecordNotFound
    raise GraphQL::ExecutionError, "not found"
  rescue ActiveRecord::RecordInvalid => e
    errors_for(e.record)
  end

  private

  # TODO: move file validation to the model
  def validate_online_upload(assignment, attachments, is_proxy: false)
    if attachments.blank?
      return validation_error(
        I18n.t("You must attach at least one file to this assignment"),
        attribute: "file_ids"
      )
    end

    # Probably a superfluous check considering how we retrieve the attachments
    attachments.each { |attachment| verify_authorized_action!(attachment, :read) } unless is_proxy

View on GitHub (pinned to 1c9f0bb801)