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

Allocation rule not found

Error message

Allocation rule not found

What it means

DeleteAllocationRule's get_allocation_rule does AllocationRule.active.find(rule_id) and rescues ActiveRecord::RecordNotFound, converting it to GraphQL::ExecutionError "Allocation rule not found". It fires when the given rule id doesn't match an active (non-deleted) AllocationRule.

Solutions

  1. Query the course's allocationRules via GraphQL and delete only an id present in the active list.
  2. Handle the already-deleted case idempotently on the client (treat the error as success if the rule is gone).
  3. Verify the id format matches what the mutation expects (relay_or_legacy id).
  4. Confirm you're operating in the correct course/shard context.

Example fix

// before
deleteAllocationRule(input: { id: deletedRuleId })
// after
const rule = course.allocationRules.find(r => r.id === ruleId)
if (rule) deleteAllocationRule(input: { id: ruleId })
Defensive patterns

Strategy: validation

Validate before calling

const rule = course.allocationRules?.nodes?.find(r => r._id === ruleId || r.id === ruleId)
if (!rule) throw new SkipError('allocation rule not active')

Type guard

function isActiveRule(rules, id) { return (rules || []).some(r => String(r._id ?? r.id) === String(id)); }

Try / catch

try {
  await deleteAllocationRule({ id: ruleId })
} catch (e) {
  if (e.message.includes('Allocation rule not found')) {
    refetchRules(); // already gone, treat as success
  } else throw e;
}

Prevention

When it happens

Trigger: Calling deleteAllocationRule with an id that never existed, was already deleted (soft-deleted, so excluded by .active scope), or belongs to another course/shard; passing a relay/global id where a legacy numeric id is expected or vice versa.

Common situations: Double-delete from a UI retry after the first delete succeeded; stale list cache showing a deleted rule; wrong course context; id from a different environment.

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/4309d9f1b4ee3b86. Report an issue: GitHub.

Appendix: source

Thrown at app/graphql/mutations/delete_allocation_rule.rb:50

    verify_authorized_action!(assignment, :delete)
    context[:deleted_models] ||= {}
    context[:deleted_models][:allocation_rule] = record
    record.destroy
    {
      allocation_rule_id: record.id
    }
  end

  def self.allocation_rule_id_log_entry(_entry, context)
    context[:deleted_models][:allocation_rule]
  end

  private

  def get_allocation_rule(rule_id)
    AllocationRule.active.find(rule_id)
  rescue ActiveRecord::RecordNotFound
    raise GraphQL::ExecutionError, I18n.t("Allocation rule not found")
  end

  def validate_feature_flag!(course)
    unless course.feature_enabled?(:peer_review_allocation_and_grading)
      raise GraphQL::ExecutionError, I18n.t("peer_review_allocation_and_grading feature flag is not enabled for this course")
    end
  end
end

View on GitHub (pinned to 1c9f0bb801)