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
- Check submission.submission_drafts.any? client-side before calling the mutation
- Treat this error as an idempotent success if the goal is simply 'no drafts remain'
- Verify you are targeting the correct submission_id (current attempt)
- 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
- Check draft presence before rendering discard-draft UI
- Treat deletion as idempotent client-side
- Clear draft state after successful submission
- Use the submission id of the current attempt
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
- Enrollment is not in invited state
- not found
- and cannot be used together
- and cannot be used together
- A course with that id does not exist
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)