{"record":{"id":"e0077d2a777676c4","repo":"instructure/canvas-lms","slug":"not-found-create-submission-draft","errorCode":null,"errorMessage":"not found","messagePattern":"not found","errorType":"exception","errorClass":"GraphQL::ExecutionError","httpStatus":null,"severity":"error","filePath":"app/graphql/mutations/create_submission_draft.rb","lineNumber":92,"sourceCode":"      submission_draft.resource_link_lookup_uuid = input[:resource_link_lookup_uuid]\n    when \"media_recording\"\n      submission_draft.media_object_id = input[:media_id]\n    when \"online_text_entry\"\n      submission_draft.body = input[:body]\n    when \"online_upload\"\n      file_ids = (input[:file_ids] || []).compact.uniq\n      attachments = get_and_verify_attachments!(file_ids)\n      verify_allowed_extensions!(submission.assignment, attachments)\n      submission_draft.attachments = attachments\n    when \"online_url\"\n      submission_draft.url = input[:url]\n    end\n\n    submission_draft.save!\n\n    { submission_draft: }\n  rescue ActiveRecord::RecordNotFound\n    raise GraphQL::ExecutionError, \"not found\"\n  rescue ActiveRecord::RecordInvalid => e\n    # activerecord validation is not robust to race condition\n    #   multiple concurrent requests may penetrate activerecord validations\n    #   and save dup records for a combination of submission_id and attempt\n    # If it happened, following saves will be blocked by activerecord validation\n    # Ideally, an unique index should be defined, but with many existing records,\n    #   creating unique index may fail without cleaning data first.\n    if submission_draft.present?\n      submission_drafts = SubmissionDraft.where(\n        submission: submission_draft.submission,\n        submission_attempt: submission_draft.submission_attempt\n      )\n      if submission_drafts.count > 1 && !@retried\n        @retried = true\n        submission_drafts.where.not(id: submission_draft.id).destroy_all\n        retry\n      end\n    end","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/graphql/mutations/create_submission_draft.rb#L74-L110","documentation":"CreateSubmissionDraft#resolve wraps its work in a rescue for ActiveRecord::RecordNotFound and re-raises it as GraphQL::ExecutionError \"not found\". It fires when a record required to build the submission draft (typically the Submission via the given id, or an attachment/media record) cannot be found for the current context.","triggerScenarios":"Calling createSubmissionDraft with a submissionId that does not exist, was soft-deleted, or is not visible to current_user; referencing file/media ids that were deleted before save!; cross-context ids.","commonSituations":"Stale client cache after the assignment/submission was deleted; student unenrolled so the submission lookup fails; attempt/submission state purged; using an id from another course or shard.","solutions":["Verify the submissionId exists (Submission.active.find) and belongs to the current user before calling the mutation.","Confirm any referenced file ids / media ids still exist.","Check that the assignment and its submissions were not deleted.","Read server logs for the RecordNotFound backtrace to identify the exact missing model."],"exampleFix":"// before\ncreateSubmissionDraft(input: { submissionId: staleId, ... })\n// after\nconst sub = await apollo.query(gql`query($id: ID!){ submission(id:$id){ id } }`, { id: freshId })\nif (sub) createSubmissionDraft(input: { submissionId: freshId, ... })","handlingStrategy":"try-catch","validationCode":"const { data } = await client.query(gql`query($id: ID!){ submission(id: $id){ id } }`, { id })\nif (!data?.submission) throw new SkipError('submission missing')","typeGuard":"function canDraft(submission) { return submission != null && !submission.deleted; }","tryCatchPattern":"try {\n  await createSubmissionDraft(input)\n} catch (e) {\n  if (e.graphQLErrors?.some(g => g.message === 'not found')) {\n    await refetchAssignment(); notifyUserStale();\n  } else throw e;\n}","preventionTips":["Refetch submission state before drafting; never reuse long-lived ids.","Validate referenced file/media ids still exist before saving the draft.","Scope ids to the current course/user context."],"tags":["graphql","record-not-found","submission-draft"],"backgroundTag":"record-not-found","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}