{"record":{"id":"c32127616a6bf79d","repo":"instructure/canvas-lms","slug":"cannot-set-key-in-the-parent-assignment-for-checkpoints","errorCode":null,"errorMessage":"Cannot set #{key} in the parent assignment for checkpoints.","messagePattern":"Cannot set #(.+?) in the parent assignment for checkpoints\\.","errorType":"exception","errorClass":"GraphQL::ExecutionError","httpStatus":null,"severity":"error","filePath":"app/graphql/mutations/assignment_base.rb","lineNumber":334,"sourceCode":"    end\n  end\n\n  def ensure_restored\n    # if we are already not destroyed, then dont do anything\n    return if @working_assignment.workflow_state != \"deleted\"\n    raise GraphQL::ExecutionError, \"insufficient permission\" unless @working_assignment.grants_right? current_user, :delete\n\n    @working_assignment.restore\n  end\n\n  def validate_for_checkpoints(input_hash)\n    return unless input_hash[:for_checkpoints]\n\n    restricted_keys = %i[points_possible due_at lock_at unlock_at].freeze\n\n    restricted_keys.each do |key|\n      if input_hash.key?(key)\n        raise GraphQL::ExecutionError, \"Cannot set #{key} in the parent assignment for checkpoints.\"\n      end\n    end\n  end\nend\n","sourceCodeStart":316,"sourceCodeEnd":339,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/graphql/mutations/assignment_base.rb#L316-L339","documentation":"When for_checkpoints is true, validate_for_checkpoints forbids setting points_possible, due_at, lock_at, or unlock_at on the parent assignment — those live on the checkpoint sub-assignments. Setting any of these keys raises with the offending key name.","triggerScenarios":"A createAssignment/updateAssignment mutation with forCheckpoints: true and any of pointsPossible, dueAt, lockAt, or unlockAt present in the input (even null-keyed via input_hash.key?).","commonSituations":"Clients always serializing full assignment payloads (including nil dates) when editing checkpoint parents; copy-paste of non-checkpoint mutation payloads; form UIs submitting every field regardless of mode.","solutions":["Omit points_possible/due_at/lock_at/unlock_at from the input when forCheckpoints is true.","Set those values on each checkpoint sub-assignment instead of the parent.","Adjust client to conditionally build the input hash based on checkpoint mode.","Ensure the form doesn't include keys with nil values — presence of the key alone triggers the error."],"exampleFix":"// before\nupdateAssignment(input: { id, forCheckpoints: true, dueAt: \"2026-09-01\", pointsPossible: 10 })\n\n// after\nupdateAssignment(input: { id, forCheckpoints: true })\n// due/points set per checkpoint sub-assignment","handlingStrategy":"validation","validationCode":"const restricted = ['pointsPossible','dueAt','lockAt','unlockAt']\nif (input.forCheckpoints && restricted.some(k => k in input))\n  throw new Error('restricted field set on checkpoint parent')\n","typeGuard":null,"tryCatchPattern":"try {\n  await updateAssignment(input)\n} catch (e) {\n  if (e.message.startsWith('Cannot set')) stripRestrictedKeysAndRetry()\n}","preventionTips":["Omit (don't null) restricted keys for checkpoint parents","Conditionally build payloads by assignment mode","Set checkpoint fields on sub-assignments only"],"tags":["graphql","checkpoints","validation","assignment"],"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"}