{"record":{"id":"998bfbdf613280d0","repo":"instructure/canvas-lms","slug":"this-assignment-can-t-be-duplicated","errorCode":null,"errorMessage":"This assignment can't be duplicated","messagePattern":"This assignment can't be duplicated","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/models/abstract_assignment.rb","lineNumber":385,"sourceCode":"  end\n\n  # The relevant associations that are copied are:\n  #\n  # learning_outcome_alignments, rubric_association, wiki_page,\n  # assignment_configuration_tool_lookups\n  #\n  # In the case of wiki_page, a new wiki_page will be created.  The underlying\n  # rubric association, however, will simply point to the original rubric\n  # rather than copying the rubric.\n  #\n  # Other has_ relations are not duplicated for various reasons.\n  # These are:\n  #\n  # attachments, submissions, provisional_grades, lti stuff, discussion_topic\n  # ignores, moderated_grading_selections, teacher_enrollment\n  # TODO: Try to get more of that stuff duplicated\n  def duplicate(opts = {})\n    raise \"This assignment can't be duplicated\" unless can_duplicate?\n\n    # Don't clone a new record\n    return self if new_record?\n\n    default_opts = {\n      discussion_topic_for_checkpoints: nil,\n      duplicate_wiki_page: true,\n      duplicate_discussion_topic: true,\n      duplicate_plagiarism_tool_association: true,\n      duplicate_asset_processors: true,\n      copy_title: nil,\n      user: nil\n    }\n    opts_with_default = default_opts.merge(opts)\n\n    result = clone\n    result.saving_user = opts[:user]\n    result.all_submissions.clear","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/models/abstract_assignment.rb#L367-L403","documentation":"AbstractAssignment#duplicate refuses to duplicate assignments whose can_duplicate? is false — assignments carrying non-cloneable associations (external tool/LTI submissions, quizzes with certain settings, discussions, etc.) raise this error up front.","triggerScenarios":"Calling assignment.duplicate (or the duplicate assignment UI/API action) on an assignment where can_duplicate? returns false: LTI/external-tool assignments, assignments with submissions or provisional grades, unsupported discussion topics.","commonSituations":"Users clicking Duplicate on an external tool assignment; scripts bulk-duplicating mixed assignment sets; new submission types added without updating can_duplicate?.","solutions":["Check assignment.can_duplicate? before calling duplicate and hide/disable the Duplicate affordance otherwise","Use the supported duplicate path for quizzes/LTI tools (e.g. tool-provided duplicate handling)","If a new assignment type should be duplicable, update can_duplicate? and the duplication logic in abstract_assignment.rb"],"exampleFix":"// before\nconst canDuplicate = true; // assumed\n// after\nconst canDuplicate = assignment.canDuplicate && !(assignment.externalToolTagId);\nif (canDuplicate) duplicateAssignment(assignment); else showDuplicateDisabledTooltip();","handlingStrategy":"validation","validationCode":"const canDuplicate = assignment.canDuplicate !== false &&\n  !assignment.externalToolTagId &&\n  !['quiz','discussion_topic'].includes(assignment.submissionTypes?.[0]);\nif (!canDuplicate) throw new SkipError('Assignment cannot be duplicated');","typeGuard":"function isDuplicable(a) {\n  return a != null && typeof a.id === 'number' && a.canDuplicate === true;\n}","tryCatchPattern":"try {\n  await duplicateAssignment(assignmentId);\n} catch (e) {\n  if (e.message.includes(\"can't be duplicated\")) {\n    showError('This assignment type cannot be duplicated.');\n  }\n}","preventionTips":["Check can_duplicate? before offering the Duplicate action","Exclude external-tool and submission-bearing assignments from bulk duplication scripts","Keep can_duplicate? updated when adding new submission types","Surface the duplicate capability flag in the API response the UI consumes"],"tags":["assignments","duplicate","validation"],"backgroundTag":"unsupported-operation","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"}