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

no drafts found

Error message

no drafts found

What it means

The deleteSubmissionDraft mutation raises "no drafts found" when the submission has no associated submission_drafts. The submission exists and the user can :submit, but there is nothing to delete, so the mutation refuses rather than no-op.

Solutions

  1. Check submission.submission_drafts.any? client-side before calling the mutation
  2. Treat this error as an idempotent success if the goal is simply 'no drafts remain'
  3. Verify you are targeting the correct submission_id (current attempt)
  4. Re-create a draft before deleting if testing the delete path

Example fix

// before
raise GraphQL::ExecutionError, "no drafts found" if submission.submission_drafts.none?
// after
if submission.submission_drafts.none?
  return { submission_draft_ids: [] } # idempotent no-op
end
Defensive patterns

Strategy: fallback

Validate before calling

// query drafts first
const s = await query(submission, { id });
if (!s?.submissionDrafts?.length) return { submissionDraftIds: [] };

Type guard

function hasDrafts(submission) {
  return Array.isArray(submission?.submissionDrafts) && submission.submissionDrafts.length > 0;
}

Try / catch

try {
  return await client.mutate(DELETE_SUBMISSION_DRAFT, { submissionId });
} catch (e) {
  if (e.message === "no drafts found") return { submissionDraftIds: [] };
  throw e;
}

Prevention

When it happens

Trigger: Calling deleteSubmissionDraft for a submission where submission.submission_drafts.none? — e.g. the user never started a draft, drafts were already deleted, or drafts belong to a different attempt.

Common situations: Double-clicking a discard-drafts button, calling the mutation after drafts were already committed to a submission, or ids from a previous submission attempt.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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

Appendix: source

Thrown at app/graphql/mutations/delete_submission_draft.rb:32

# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# 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/>.
#

class Mutations::DeleteSubmissionDraft < Mutations::BaseMutation
  graphql_name "DeleteSubmissionDraft"

  argument :submission_id, ID, required: true, prepare: GraphQLHelpers.relay_or_legacy_id_prepare_func("Submission")

  field :submission_draft_ids, [ID], null: true

  def resolve(input:)
    submission = Submission.active.find(input[:submission_id])
    verify_authorized_action!(submission, :submit)

    raise GraphQL::ExecutionError, "no drafts found" if submission.submission_drafts.none?

    context[:submission] = submission
    submission_draft_ids = submission.submission_draft_ids
    submission.delete_submission_drafts!

    { submission_draft_ids: }
  rescue ActiveRecord::RecordNotFound
    raise GraphQL::ExecutionError, "not found"
  end

  def self.submission_draft_ids_log_entry(_draft_ids, context)
    # Follow the lead of CreateSubmissionDraft and return the submission object
    # for logging
    context[:submission]
  end
end

View on GitHub (pinned to 1c9f0bb801)