{"record":{"id":"6a8925d43af8d6a8","repo":"instructure/canvas-lms","slug":"assignment-overrides-are-not-allowed-in-the-parent","errorCode":null,"errorMessage":"Assignment overrides are not allowed in the parent assignment for checkpoints.","messagePattern":"Assignment overrides are not allowed in the parent assignment for checkpoints\\.","errorType":"exception","errorClass":"GraphQL::ExecutionError","httpStatus":null,"severity":"error","filePath":"app/graphql/mutations/assignment_base.rb","lineNumber":211,"sourceCode":"      input_hash[:assignment_group_id] = GraphQLHelpers.parse_relay_or_legacy_id(input_hash[:assignment_group_id], \"AssignmentGroup\")\n    end\n    if input_hash.key? :group_set_id\n      input_hash[:group_category_id] = GraphQLHelpers.parse_relay_or_legacy_id(input_hash.delete(:group_set_id), \"GroupSet\")\n    end\n\n    input_hash\n  end\n\n  def prepare_module_ids!(input_hash)\n    if input_hash.key? :module_ids\n      input_hash.delete(:module_ids).map { |id| GraphQLHelpers.parse_relay_or_legacy_id(id, \"Module\") }.map(&:to_i)\n    end\n  end\n\n  def prepare_overrides!(input_hash, api_proxy)\n    if input_hash.key?(:assignment_overrides) && input_hash[:assignment_overrides].present?\n      if input_hash[:for_checkpoints]\n        raise GraphQL::ExecutionError, \"Assignment overrides are not allowed in the parent assignment for checkpoints.\"\n      end\n\n      api_proxy.load_root_account\n      input_hash[:assignment_overrides].each do |override|\n        if override[:id].blank?\n          override.delete :id\n        else\n          override[:id] = GraphQLHelpers.parse_relay_or_legacy_id(override[:id], \"AssignmentOverride\")\n        end\n        override[:course_section_id] = GraphQLHelpers.parse_relay_or_legacy_id(override[:section_id], \"Section\") if override.key?(:section_id) && override[:section_id].present?\n        override[:group_id] = GraphQLHelpers.parse_relay_or_legacy_id(override[:group_id], \"Group\") if override.key?(:group_id) && override[:group_id].present?\n        override[:student_ids] = override[:student_ids].map { |id| GraphQLHelpers.parse_relay_or_legacy_id(id, \"User\") } if override.key?(:student_ids) && override[:student_ids].present?\n      end\n    end\n  end\n\n  def prepare_moderated_grading!(input_hash)\n    if input_hash.key? :moderated_grading","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/graphql/mutations/assignment_base.rb#L193-L229","documentation":"When creating/updating a parent assignment with `for_checkpoints: true` (discussion checkpoints), providing `assignment_overrides` is invalid; AssignmentBase.prepare_overrides! raises instead of applying them. Checkpoint sub-assignments carry their own overrides, so overrides on the parent are disallowed.","triggerScenarios":"A createAssignment/updateAssignment mutation that includes both `forCheckpoints: true` and a non-empty `assignmentOverrides` array.","commonSituations":"Migrating existing assignment code to the checkpoints model and reusing the same input payload; UI sending default override sets unconditionally; clients copying payloads from non-checkpoint assignment calls.","solutions":["Remove assignmentOverrides from the input when forCheckpoints is true.","Apply overrides to the checkpoint sub-assignments after the parent is created instead.","Only include forCheckpoints: true if you actually intend checkpoint behavior.","Branch client code: build separate payloads for checkpoint vs regular assignments."],"exampleFix":"// before\nupdateAssignment(input: { id, forCheckpoints: true, assignmentOverrides: [...] })\n\n// after\nupdateAssignment(input: { id, forCheckpoints: true }) // no overrides on parent\n// set overrides on each checkpoint assignment separately","handlingStrategy":"validation","validationCode":"if input.forCheckpoints && input.assignmentOverrides?.length\n  throw new Error('Remove assignmentOverrides for checkpoint parents')\n","typeGuard":null,"tryCatchPattern":"try {\n  await updateAssignment(input)\n} catch (e) {\n  if (e.message.includes('overrides are not allowed')) stripOverridesAndRetry()\n}","preventionTips":["Build input objects conditionally for checkpoint mode","Never blanket-serialize all assignment fields","Add client-side schema for checkpoint payloads"],"tags":["graphql","assignment-overrides","checkpoints","validation"],"backgroundTag":"mutually-exclusive-options","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"}