{"record":{"id":"d3f648fcbf2c6e20","repo":"instructure/canvas-lms","slug":"at-least-one-assessor-is-required","errorCode":null,"errorMessage":"At least one assessor is required","messagePattern":"At least one assessor is required","errorType":"exception","errorClass":"GraphQL::ExecutionError","httpStatus":null,"severity":"error","filePath":"app/graphql/mutations/allocation_rule_base.rb","lineNumber":100,"sourceCode":"      reciprocal = input[:reciprocal]\n\n      if reciprocal\n        if assessor_ids.length > 1\n          raise GraphQL::ExecutionError, I18n.t(\"Only one assessor is allowed when creating reciprocal rules\")\n        end\n        if assessee_ids.length > 1\n          raise GraphQL::ExecutionError, I18n.t(\"Only one assessee is allowed when creating reciprocal rules\")\n        end\n      elsif applies_to_assessor\n        if assessor_ids.length > 1\n          raise GraphQL::ExecutionError, I18n.t(\"Only one assessor is allowed when rule applies to assessor\")\n        end\n      elsif assessee_ids.length > 1\n        raise GraphQL::ExecutionError, I18n.t(\"Only one assessee is allowed when rule applies to assessee\")\n      end\n\n      if assessor_ids.empty?\n        raise GraphQL::ExecutionError, I18n.t(\"At least one assessor is required\")\n      end\n      if assessee_ids.empty?\n        raise GraphQL::ExecutionError, I18n.t(\"At least one assessee is required\")\n      end\n\n      if assessor_ids.length > 50\n        raise GraphQL::ExecutionError, I18n.t(\"A maximum of 50 assessors can be provided at once\")\n      end\n      if assessee_ids.length > 50\n        raise GraphQL::ExecutionError, I18n.t(\"A maximum of 50 assessees can be provided at once\")\n      end\n    end\n\n    def get_assignment(assignment_id)\n      Assignment.active.find(assignment_id)\n    rescue ActiveRecord::RecordNotFound\n      raise GraphQL::ExecutionError, I18n.t(\"Assignment not found\")\n    end","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/graphql/mutations/allocation_rule_base.rb#L82-L118","documentation":"Raised by validate_id_arrays! in AllocationRuleBase when the assessor_ids array is empty. Every allocation rule requires at least one assessor, so an empty list is rejected with a GraphQL ExecutionError before any rule is created.","triggerScenarios":"Calling an allocation-rule create mutation with assessorIds: [] (or omitted/null resolving to []) after the cardinality checks pass.","commonSituations":"A UI filter matches no eligible assessors (e.g. all students already assigned) and the empty selection is still submitted; a script builds the ID array from an upstream query that returned nothing; a form reset clears selections but submit stays enabled.","solutions":["Provide at least one assessor ID in the mutation input.","Disable submit when no assessor is selected and/or show the error client-side.","Check the query that generates assessor IDs for empty results before calling the mutation.","Confirm the IDs are valid active users eligible as assessors in the course."],"exampleFix":"// before\n{ assessorIds: [], assesseeIds: [\"21\"] }\n// after\n{ assessorIds: [\"11\"], assesseeIds: [\"21\"] }","handlingStrategy":"validation","validationCode":"if (!Array.isArray(input.assessorIds) || input.assessorIds.length === 0) {\n  throw new Error('Select at least one assessor before submitting');\n}","typeGuard":"function hasAssessors(input) {\n  return Array.isArray(input.assessorIds) && input.assessorIds.length > 0;\n}","tryCatchPattern":"try {\n  await createAllocationRules(input);\n} catch (e) {\n  if (e.message.includes('At least one assessor is required')) {\n    // prompt user to pick assessors\n  }\n}","preventionTips":["Disable submit until at least one assessor is chosen","Check upstream queries for empty assessor results","Handle 'no eligible assessors' states in the UI","Never submit arrays built from possibly-empty data without a length check"],"tags":["graphql","validation","empty-array","canvas"],"backgroundTag":"empty-required-field","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"}