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

insufficient permission

Error message

insufficient permission

What it means

GraphQL mutation for outcome proficiency upserts raises this when the current user lacks the :manage_proficiency_scales right on the target context (account or course). check_permission is called before any upsert work, so the mutation always fails closed when the permission grant is absent.

Solutions

  1. Grant the user's role the manage_proficiency_scales permission on the target account or course (Account > Permissions).
  2. Verify with context.grants_right?(user, :manage_proficiency_scales) in a Rails console before calling the mutation.
  3. Use a token/session of a user with the required permission instead.

Example fix

// before
mutation { createOutcomeProficiency(input: {contextId: "..."}) { ... } }
// after
// first ensure caller has permission, e.g. as an account admin with mastery-scale rights,
// or fix role overrides so manage_proficiency_scales is enabled for the user's role
Defensive patterns

Strategy: validation

Validate before calling

// pre-check in console/server code before calling the mutation
raise "no permission" unless context.grants_right?(current_user, :manage_proficiency_scales)

Try / catch

try { await mutate(); } catch (e) { if (e.message === 'insufficient permission') showPermissionDialog(); }

Prevention

When it happens

Trigger: Calling OutcomeProficiencyCreate or OutcomeProficiencyUpdate mutation as a user (teacher, custom role, admin of a sub-account) whose effective rights on context do not include manage_proficiency_scales.

Common situations: Non-admin users or custom roles missing the 'Learning Outcomes - add/edit/mastery scales' permission; attempting to set mastery scales at an account level with only course-level rights; API tokens of a user rather than an site admin.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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

Appendix: source

Thrown at app/graphql/mutations/outcome_proficiency_base.rb:52

  end

  protected

  def attrs(input)
    {
      outcome_proficiency_ratings: input[:proficiency_ratings].map do |rating|
        OutcomeProficiencyRating.new(**rating)
      end
    }
  end

  def context_taken?(record)
    error = record.errors.first
    error && error.attribute == :context_id && error.message == "has already been taken"
  end

  def check_permission(context)
    raise GraphQL::ExecutionError, "insufficient permission" unless context.grants_right? current_user, :manage_proficiency_scales
  end

  def upsert(input, existing_record: nil, context: nil)
    record = existing_record || OutcomeProficiency.find_by(context:)
    if record
      record.assign_attributes(workflow_state: "active")
      record.replace_ratings(input[:proficiency_ratings])
      record.assign_attributes(context:) unless context.nil?
    else
      record = OutcomeProficiency.new(context:, **attrs(input.to_h))
    end
    if record.save
      { outcome_proficiency: record }
    elsif existing_record.nil? && context_taken?(record)
      upsert(input, context:)
    else
      errors_for(record)
    end

View on GitHub (pinned to 1c9f0bb801)