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

individual ratings data input with…

Error message

individual ratings data input with acount_level_mastery_scale FF enabled

What it means

base_learning_outcome_mutation#ratings_attrs rejects individual-outcome ratings input (calculation_method, calculation_int, mastery_points, ratings) when the root account has the account_level_mastery_scales feature flag enabled. With that flag on, mastery scales must be managed at the account level, so per-outcome ratings data in the mutation input is an unsupported operation and raises this ExecutionError.

Solutions

  1. Remove calculation_method/calculation_int/mastery_points/ratings from the mutation input
  2. Manage mastery scales via the account-level mastery scale endpoints instead
  3. Disable account_level_mastery_scales on the root account if per-outcome ratings must still be used (not recommended)
  4. Update client integrations to detect the flag and branch their payloads

Example fix

// before
updateLearningOutcome(input: { id: $id, masteryPoints: 3, ratings: $ratings })
// after
// with account_level_mastery_scales enabled:
updateLearningOutcome(input: { id: $id, title: $title }) // manage scales at account level
Defensive patterns

Strategy: validation

Validate before calling

const account = await canvas.get(`/api/v1/accounts/${rootAccountId}/features`)
const scalesEnabled = account.includes('account_level_mastery_scales')
if (scalesEnabled && (input.masteryPoints || input.ratings || input.calculationMethod)) {
  throw new Error('per-outcome ratings not allowed with account_level_mastery_scales enabled')
}

Type guard

function hasRatingsInput(i) { return i != null && ['calculationMethod','calculationInt','masteryPoints','ratings'].some(k => i[k] !== undefined) }

Try / catch

try {
  await client.mutate({ mutation: UPDATE_LEARNING_OUTCOME, variables: { input } })
} catch (e) {
  if (e.message.includes('individual ratings data input')) {
    // strip ratings fields and retry with account-level scales
  }
}

Prevention

When it happens

Trigger: Calling createLearningOutcome/updateLearningOutcome with input containing calculation_method, calculation_int, mastery_points, or ratings while context.root_account.feature_enabled?(:account_level_mastery_scales) is true and a context is present.

Common situations: Clients built before the account-level mastery scales feature send legacy per-outcome ratings payloads against an account where the flag was turned on; scripts or LTI tools updating mastery points directly on outcomes.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/dbfade89206f5f6a. Report an issue: GitHub.

Appendix: source

Thrown at app/graphql/mutations/base_learning_outcome_mutation.rb:48

    argument :title, String, required: true
    argument :vendor_guid, String, required: false

    field :learning_outcome, Types::LearningOutcomeType, null: true

    protected

    def attrs(input, context)
      outcome_input = input.to_h.slice(:title, :display_name, :description, :vendor_guid)

      outcome_input.merge ratings_attrs(input, context)
    end

    def ratings_attrs(input, context)
      ratings_input = input.to_h.slice(:calculation_method, :calculation_int, :mastery_points, :ratings)

      return {} unless ratings_input.count.positive? && context

      raise GraphQL::ExecutionError, I18n.t("individual ratings data input with acount_level_mastery_scale FF enabled") if context.root_account.feature_enabled?(:account_level_mastery_scales)

      updated_ratings_attrs = {}
      rubric_criterion = {}
      rubric_criterion[:mastery_points] = ratings_input[:mastery_points] if ratings_input[:mastery_points]
      rubric_criterion[:ratings] = ratings_input[:ratings] if ratings_input[:ratings]
      updated_ratings_attrs[:calculation_method] = ratings_input[:calculation_method] if ratings_input[:calculation_method]
      updated_ratings_attrs[:calculation_int] = ratings_input[:calculation_int] if ratings_input[:calculation_int]
      updated_ratings_attrs[:rubric_criterion] = rubric_criterion if rubric_criterion.present?

      updated_ratings_attrs
    end
  end
end

View on GitHub (pinned to 1c9f0bb801)