instructure/canvas-lms · error · GraphQL::ExecutionError
Assignment not found
Error message
Assignment not found
What it means
Raised by get_assignment in AllocationRuleBase when Assignment.active.find(assignment_id) raises ActiveRecord::RecordNotFound, i.e. no active assignment with the given ID exists (missing, deleted, or soft-deleted via a non-'active' workflow state). It is converted into a GraphQL ExecutionError 'Assignment not found'.
Solutions
- Verify the assignmentId exists: Assignment.active.find(id) in the Rails console on the correct shard.
- Check the assignment's workflow_state — a deleted assignment will not be found by the active scope.
- Refresh the client's assignment data; the assignment may have been deleted after page load.
- Confirm you are operating on the correct Canvas environment/shard and root account.
Example fix
// before
mutation { createAllocationRules(input: { assignmentId: "999999", ... }) } // ID deleted/nonexistent
// after: resolve a live assignment first
assignment = course.assignments.active.where(name: "Peer Review 1").first!
# use assignment.id (GlobalID string) in the mutation input Defensive patterns
Strategy: try-catch
Validate before calling
const assignment = await canvasApi.getAssignment(courseId, assignmentId);
if (!assignment || assignment.workflow_state !== 'active') {
throw new Error(`Assignment ${assignmentId} is missing or not active`);
}
// then run the allocation rule mutation Type guard
function isActiveAssignment(a) {
return a != null && typeof a.id === 'string' && a.workflow_state === 'active';
} Try / catch
try {
await createAllocationRules({ assignmentId, ... });
} catch (e) {
if (e.message.includes('Assignment not found')) {
// refetch assignment list; id may be deleted or from another environment
}
} Prevention
- Resolve assignment IDs from a fresh API query, never hardcode across environments
- Check workflow_state is 'active' (deleted assignments are excluded by the active scope)
- Be aware of shard/root-account scoping in multi-shard installs
- Handle assignments deleted after page load by refreshing before submit
When it happens
Trigger: Calling an allocation-rule mutation with an assignmentId that does not exist, belongs to a deleted assignment (workflow_state != 'active'), is on the wrong shard/root account, or is a malformed/nonexistent ID in the environment.
Common situations: Staging IDs used against production data; the assignment was deleted after the UI loaded; the assignment is 'soft deleted' so active scope excludes it; cross-shard ID handling issues in multi-shard Canvas installs.
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
- A maximum of 50 assessees can be provided at once
- A maximum of 50 assessors can be provided at once
- Allocation rule not found
- An assignment with that id does not exist
- Assignment has self assessments or due date has passed
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/a448a18cf0046c8f.
Report an issue: GitHub.
Appendix: source
Thrown at app/graphql/mutations/allocation_rule_base.rb:117
if assessor_ids.empty?
raise GraphQL::ExecutionError, I18n.t("At least one assessor is required")
end
if assessee_ids.empty?
raise GraphQL::ExecutionError, I18n.t("At least one assessee is required")
end
if assessor_ids.length > 50
raise GraphQL::ExecutionError, I18n.t("A maximum of 50 assessors can be provided at once")
end
if assessee_ids.length > 50
raise GraphQL::ExecutionError, I18n.t("A maximum of 50 assessees can be provided at once")
end
end
def get_assignment(assignment_id)
Assignment.active.find(assignment_id)
rescue ActiveRecord::RecordNotFound
raise GraphQL::ExecutionError, I18n.t("Assignment not found")
end
def process_allocation_rules(allocation_rules)
if allocation_rules.all?(&:valid?)
allocation_rules.each(&:save!)
{ allocation_rules: }
else
invalid_rules = allocation_rules.reject(&:valid?)
all_allocation_errors = []
invalid_rules.each do |invalid_rule|
rule_errors = allocation_errors_for(invalid_rule)
all_allocation_errors.concat(rule_errors[:allocation_errors])
end
{
allocation_errors: all_allocation_errors
}View on GitHub (pinned to 1c9f0bb801)