Why Canvas counts a graded discussion as submitted after one post

In a graded Canvas discussion, the first thing you post submits the assignment, whether it is your main post or a reply to a classmate. Canvas dates the submission to your earliest post. From then on the discussion counts as done: it leaves your To Do list, shows as done in your planner, and Canvas will not mark it Missing on its own. Canvas does not count the replies an instructor asks for unless the discussion uses Discussion Checkpoints, a feature your school has to turn on. With checkpoints, the main post and the replies are two items with their own due dates, and the replies item is submitted only once you have posted the required number. If you delete every post you made, Canvas takes the submission back.

What you see

The instructions say to post by Wednesday and reply to two classmates by Sunday. You post on Wednesday, and the discussion leaves your To Do list. Sunday comes, and nothing in Canvas reminds you about the replies.

Or Canvas shows a discussion as submitted when all you did was reply to someone. Or the same discussion shows up twice, once for "Reply to Topic" and once for "Required Replies".

Why it happens

Any post submits a graded discussion. When you save a post in a discussion that is an assignment, Canvas runs the step that submits it for you. Without checkpoints, that step looks at every post you have in the discussion, main posts and replies alike, and submits the assignment with the time of the earliest one. A reply to a classmate is enough. Once a discussion submission exists, a later post does not submit it again.

After that, Canvas treats it as done. Canvas's To Do API drops an assignment once your submission has a type, and the planner counts it complete once it has a submitted time. Canvas's own check for Missing work stops once a submitted time is there, so a submitted discussion is not marked Missing unless your instructor sets that status by hand. (For the rest of that check, see when Canvas marks your work Missing.)

Required replies are not tracked without checkpoints. A plain graded discussion has one due date and one submission. The step that submits it does not count replies. The number of replies your instructor wants, and when, lives only in the instructions.

With checkpoints, the replies are their own item. Discussion Checkpoints is a Canvas feature that lets an instructor give the main post and the replies separate due dates, graded separately. A school's Canvas admin turns it on for the account; in Canvas's source it is off until an admin does. With it on, your first main post submits the "Reply to Topic" part, and replies to other posts submit nothing until there are as many as the instructor required. Canvas's calendar names the two parts after the discussion: "Reply to Topic" and "Required Replies", with the number required in parentheses. Canvas's To Do API lists the two parts for courses where checkpoints are on.

Deleting posts can take the submission back. If you delete posts and none of yours is left, Canvas sets the submission back to unsubmitted. With checkpoints, deleting replies so that fewer than the required number remain unsubmits the replies part.

What you can check

Margin can only show what Canvas exposes — check your syllabus too.

What an instructor or admin can do

Evidence

canvas-lms, app/models/discussion_entry.rb:72 (master at 1c9f0bb, retrieved 2026-11-11): every saved post runs context_module_action_later, which sends the discussion a :contributed action (:512-519). The discussion then submits for a student (app/models/discussion_topic.rb:1619-1623):

if for_assignment?
  tags_to_update += assignment.context_module_tags
  if context.grants_right?(user, :participate_as_student) && assignment.visible_to_user?(user) && [:contributed, :deleted].include?(action)
    only_update = (action == :deleted) # if we're deleting an entry, don't make a submission if it wasn't there already
    ensure_submission(user, only_update:)

app/models/discussion_topic.rb:1652-1655, without checkpoints, the time of your earliest post of any kind:

else
  submitted_at = all_entries_for_user.minimum(:created_at)

  submission = ensure_particular_submission(assignment, user, submitted_at, only_update:)

app/models/discussion_entry.rb:467, what "all entries for user" means, replies included:

scope :all_for_user, ->(user) { active.where(user_id: user) }

app/models/discussion_topic.rb:1672-1674, the submission itself, made unless a discussion submission already exists (:1670-1671):

submission = assignment.submit_homework(user,
                                        submission_type: "discussion_topic",
                                        submitted_at:)

Canvas's To Do API drops an assignment once the student's submission has a type (app/models/abstract_assignment.rb:3494-3501), the planner once it has a submitted time (lib/plannable.rb:45-77); the Dashboard To Do list reads the planner (ui/shared/planner/actions/sidebar-actions.js:102). Canvas's Missing check, app/models/submission.rb:2830:

return false if submitted_at.present?

config/feature_flags/vice_release_flags.yml:94-102, the checkpoints feature:

discussion_checkpoints:
  state: allowed
  display_name: Discussion Checkpoints
  description: |-
    Enables checkpoints for graded discussions. Checkpoints allow teachers to
    create separate due dates for the initial response and replies. The initial
    response and replies are then graded separately, and those grades are
    combined to form a final discussion grade.
  applies_to: Account

allowed is Canvas's off-by-default state (lib/feature.rb:141, STATE_DEFAULT_OFF = "allowed"), and a course takes the setting from its account (app/models/course.rb:1863-1865). With checkpoints, app/models/discussion_topic.rb:1637-1651 submits the main-post part from your first top-level post, and the replies part only here (:1647):

if reply_to_entries.any? && enough_replies_for_checkpoint?(reply_to_entries)

app/models/discussion_topic.rb:2307-2309:

def enough_replies_for_checkpoint?(reply_to_entries)
  reply_to_entries.count >= reply_to_entry_required_count
end

The two parts are titled "Reply to Topic" and "Required Replies (N)" (app/models/sub_assignment.rb:107-116) on the calendar (lib/api/v1/calendar_event.rb:260) and in the calendar feed (app/models/calendar_event.rb:795). Canvas's To Do API adds them for courses with checkpoints on (app/controllers/users_controller.rb:999-1033).

Deleting a post calls update_topic_submission (app/models/discussion_entry.rb:252-256). Without checkpoints, when no active post of yours is left (:330-333):

else
  submission.workflow_state = "unsubmitted"
  submission.submission_type = nil
  submission.submitted_at = nil

With checkpoints, the replies part is unsubmitted when fewer replies than required remain (:307-316).