{"record":{"id":"a87f821d2017f865","repo":"instructure/canvas-lms","slug":"a-and-b-cannot-be-used-together-post-assignment-grades","errorCode":null,"errorMessage":"{a} and {b} cannot be used together","messagePattern":"(.+?) and (.+?) cannot be used together","errorType":"exception","errorClass":"GraphQL::ExecutionError","httpStatus":null,"severity":"error","filePath":"app/graphql/mutations/post_assignment_grades.rb","lineNumber":55,"sourceCode":"      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)\n    visible_enrollments = visible_enrollments.where(user_id: input[:only_student_ids]) if input[:only_student_ids]\n    visible_enrollments = visible_enrollments.where.not(user_id: input[:skip_student_ids]) if input[:skip_student_ids]\n\n    submissions_scope = input[:graded_only] ? assignment.submissions.postable : assignment.submissions\n    submissions_scope = submissions_scope.joins(user: :enrollments).merge(visible_enrollments)\n    submission_ids = submissions_scope.pluck(:id)\n    progress = course.progresses.new(tag: \"post_assignment_grades\")\n\n    posting_params = {\n      graded_only: !!input[:graded_only],\n      section_names: sections&.pluck(:name)\n    }\n\n    if progress.save\n      progress.process_job(","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/graphql/mutations/post_assignment_grades.rb#L37-L73","documentation":"Raised when both only_student_ids and skip_student_ids are provided to postAssignmentGrades. The two inputs are mutually exclusive filters on visible enrollments; the I18n template interpolates the option names into the message.","triggerScenarios":"postAssignmentGrades with both onlyStudentIds and skipStudentIds arrays present in the input object.","commonSituations":"UI state accumulation where a selection list (only) and an exclusion list (skip) are both populated from different controls; merging saved filters with current ones.","solutions":["Send only one of only_student_ids / skip_student_ids; clear the other before submitting.","Compute a single student id list client-side and pass it via only_student_ids.","Server preference impossible here — the API will always reject the combination, so validate in the client."],"exampleFix":"// before\npostAssignmentGrades(input: {assignmentId, onlyStudentIds: [\"1\"], skipStudentIds: [\"2\"]})\n// after\npostAssignmentGrades(input: {assignmentId, onlyStudentIds: [\"1\"]})","handlingStrategy":"validation","validationCode":"if (input.onlyStudentIds?.length && input.skipStudentIds?.length)\n  throw new Error('only_student_ids and skip_student_ids are mutually exclusive');","typeGuard":null,"tryCatchPattern":"try { await post(); } catch (e) { if (/cannot be used together/.test(e.message)) clearExclusiveInputs(); }","preventionTips":["Treat only/skip lists as one radio-selected filter mode in the UI.","Clear the counterpart list whenever one is populated.","Add a form-level validation before submit."],"tags":["graphql","input-validation","mutually-exclusive"],"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"}