{"record":{"id":"1dce8eb9a92f8964","repo":"instructure/canvas-lms","slug":"not-found-post-assignment-grades","errorCode":null,"errorMessage":"not found","messagePattern":"not found","errorType":"exception","errorClass":"GraphQL::ExecutionError","httpStatus":null,"severity":"error","filePath":"app/graphql/mutations/post_assignment_grades.rb","lineNumber":40,"sourceCode":"  graphql_name \"PostAssignmentGrades\"\n\n  argument :assignment_id, ID, required: true, prepare: GraphQLHelpers.relay_or_legacy_id_prepare_func(\"Assignment\")\n  argument :graded_only, Boolean, required: false\n  argument :only_student_ids, [ID], required: false, prepare: GraphQLHelpers.relay_or_legacy_ids_prepare_func(\"User\")\n  argument :section_ids, [ID], required: false, prepare: GraphQLHelpers.relay_or_legacy_ids_prepare_func(\"Section\")\n  argument :skip_student_ids, [ID], required: false, prepare: GraphQLHelpers.relay_or_legacy_ids_prepare_func(\"User\")\n\n  field :assignment, Types::AssignmentType, null: true\n  field :progress, Types::ProgressType, null: true\n  field :sections, [Types::SectionType], null: true\n\n  def resolve(input:)\n    begin\n      assignment = AbstractAssignment.find_assignment_or_peer_review(input[:assignment_id])\n      course = assignment.context\n      sections = input[:section_ids] ? course.course_sections.where(id: input[:section_ids]) : nil\n    rescue ActiveRecord::RecordNotFound\n      raise GraphQL::ExecutionError, \"not found\"\n    end\n\n    verify_authorized_action!(assignment, :grade)\n\n    unless assignment.grades_published?\n      raise GraphQL::ExecutionError, \"Assignments under moderation cannot be posted before grades are published\"\n    end\n    raise GraphQL::ExecutionError, \"Anonymous assignments cannot be posted by section\" if sections && assignment.anonymous_grading?\n\n    if input[:graded_only] && assignment.anonymous_grading\n      raise GraphQL::ExecutionError, \"Anonymous assignments cannot be posted by graded only\"\n    end\n\n    if input[:only_student_ids] && input[:skip_student_ids]\n      raise GraphQL::ExecutionError, I18n.t(\"{a} and {b} cannot be used together\", a: \"only_student_ids\", b: \"skip_student_ids\")\n    end\n\n    visible_enrollments = course.apply_enrollment_visibility(course.student_enrollments, current_user, sections)","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/graphql/mutations/post_assignment_grades.rb#L22-L58","documentation":"PostAssignmentGrades mutation resolves the assignment via AbstractAssignment.find_assignment_or_peer_review; if the id does not resolve (or course/section lookup raises RecordNotFound inside the same begin block), it is translated into a generic GraphQL 'not found' ExecutionError.","triggerScenarios":"Posting grades with an assignmentId that is deleted, nonexistent, belongs to another course/shard, or is not an assignment or peer-review sub-assignment.","commonSituations":"Stale client-side IDs after an assignment deletion; copying IDs across Canvas shards/environments; passing a discussion topic or quiz id instead of its assignment id.","solutions":["Verify the assignment exists: Assignment.find(id) in console, and that it is in the same course.","Use the assignment's global or correct-shard id; confirm peer-review sub-assignments only where intended.","Check the assignment was not deleted (workflow_state != 'deleted') and re-fetch fresh ids."],"exampleFix":"// before\npostAssignmentGrades(input: {assignmentId: \"1234\", ...}) // deleted/stale id\n// after\nconst assignment = await fetchAssignment(id); // 404-check before posting\nif (!assignment) return; // surface a friendly 'assignment no longer exists' message","handlingStrategy":"validation","validationCode":"if (!assignmentId) throw new Error('assignmentId required');\nconst assignment = await fetchAssignment(assignmentId); // expect 200\nif (!assignment) return notFound();","typeGuard":"const isValidAssignment = (a) => a && typeof a.id === 'string' && a.id.length > 0;","tryCatchPattern":"try { await postAssignmentGrades({input}); } catch (e) { if (e.message === 'not found') notifyStaleAssignment(); else throw e; }","preventionTips":["Re-fetch assignment ids from the API instead of caching them across sessions.","Use global ids when crossing shard boundaries.","Handle deletions in the UI so stale ids cannot be submitted."],"tags":["graphql","not-found","assignments"],"backgroundTag":"record-not-found","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"}