instructure/canvas-lms · error · GraphQL::ExecutionError

An assignment with that id does not exist

Error message

An assignment with that id does not exist

What it means

SetAssignmentPostPolicy looks up the assignment with `AbstractAssignment.find_assignment_or_peer_review(input[:assignment_id])` and rescues ActiveRecord::RecordNotFound, raising GraphQL::ExecutionError "An assignment with that id does not exist". This is an explicit, user-friendly conversion of a missing-assignment lookup into a GraphQL error before any authorization or post-policy changes occur.

Solutions

  1. Verify the assignment id by querying it first (e.g. legacyNode with type Assignment) before mutating.
  2. Refresh any cached assignment lists to drop deleted assignments.
  3. Confirm you are calling against the correct Canvas environment/shard.
  4. If the id came from a peer review, use the id expected by find_assignment_or_peer_review (the assignment id, not the peer review sub-id).

Example fix

// before
setAssignmentPostPolicy(input: { assignmentId: "404", postManually: true })
// after
query { legacyNode(__typename: "Assignment", id: "404") { _id } }
// only then call the mutation with a confirmed id
Defensive patterns

Strategy: validation

Validate before calling

const node = await client.query({ query: LEGACY_NODE_QUERY, variables: { id: assignmentId, type: 'Assignment' } });
if (!node?.data?.legacyNode) throw new Error(`assignment ${assignmentId} does not exist`);

Type guard

function assignmentExists(node) { return node?.__typename === 'Assignment' && node._id != null; }

Try / catch

try {
  await client.mutate({ mutation: SET_ASSIGNMENT_POST_POLICY, variables });
} catch (e) {
  if (e.graphQLErrors?.some(g => g.message.includes('does not exist'))) {
    // drop the id from local state and prompt the user to reselect
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling setAssignmentPostPolicy with an assignment_id that does not exist, was deleted, or (for peer review lookups) whose root/sub-assignment cannot be resolved on the current shard.

Common situations: Automated scripts iterating a cached assignment list after some assignments were deleted; copying an id from a peer-review sub-assignment URL; wrong course context or shard; ids taken from another Canvas instance (test vs production).

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/2cc07aa375163d0d. Report an issue: GitHub.

Appendix: source

Thrown at app/graphql/mutations/set_assignment_post_policy.rb:36

# with this program. If not, see <http://www.gnu.org/licenses/>.
#

class Mutations::SetAssignmentPostPolicy < Mutations::BaseMutation
  graphql_name "SetAssignmentPostPolicy"

  argument :assignment_id, ID, required: true, prepare: GraphQLHelpers.relay_or_legacy_id_prepare_func("Assignment")
  argument :post_comments_at, String, required: false
  argument :post_grades_at, String, required: false
  argument :post_manually, Boolean, required: true

  field :post_policy, Types::PostPolicyType, null: true

  def resolve(input:)
    begin
      assignment = AbstractAssignment.find_assignment_or_peer_review(input[:assignment_id])
      course = assignment.context
    rescue ActiveRecord::RecordNotFound
      raise GraphQL::ExecutionError, "An assignment with that id does not exist"
    end

    verify_authorized_action!(course, :manage_grades)

    if input[:post_manually] == false
      raise GraphQL::ExecutionError, I18n.t("Anonymous assignments must be manually posted") if assignment.anonymous_grading?

      if assignment.moderated_grading? && !assignment.grades_published?
        raise GraphQL::ExecutionError, I18n.t("Moderated assignments must be manually posted until grades are released")
      end
    end

    assignment.ensure_post_policy(post_manually: input[:post_manually])

    if Account.site_admin.feature_enabled?(:scheduled_feedback_releases) && input[:post_manually] == true
      is_post_params_blank = input[:post_comments_at].blank? && input[:post_grades_at].blank?

      if !is_post_params_blank

View on GitHub (pinned to 1c9f0bb801)