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

Insufficient permissions

Error message

Insufficient permissions

What it means

After loading the Score, resolve checks score.grants_right?(current_user, session, :update_custom_status). If the acting user lacks that permission on the score (e.g. not a teacher/admin in the course), an "Insufficient permissions" ExecutionError is raised.

Solutions

  1. Act as a user with the update_custom_status permission (teacher/admin) in the course
  2. Re-enable update_custom_status for the relevant role under Account Permissions
  3. Confirm the enrollment_id belongs to a course where the acting user has grading rights

Example fix

// before
customGradeStatus(enrollmentId: 12, customGradeStatusId: 3) # with a student token
// after
if enrollment.score.grants_right?(current_user, session, :update_custom_status)
  customGradeStatus(enrollmentId: 12, customGradeStatusId: 3)
end
Defensive patterns

Strategy: try-catch

Validate before calling

// Ruby
allowed = enrollment.score&.grants_right?(current_user, session, :update_custom_status)

Try / catch

// Ruby
begin
  mutation
rescue GraphQL::ExecutionError => e
  show_permission_notice if e.message == "Insufficient permissions"
end

Prevention

When it happens

Trigger: A student or observer calls setOverrideStatus on their own/another enrollment; a teacher without update_custom_status rights (permission turned off at the account/sub-account role level) attempts to set a custom status.

Common situations: Role customization in Account > Permissions removed update_custom_status from the Teacher role; client accidentally uses a non-teacher token; cross-course enrollment id passed in.

Understand the failure class

Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at app/graphql/mutations/set_override_status.rb:32

# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
# details.
#
# You should have received a copy of the GNU Affero General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
module Mutations
  class SetOverrideStatus < BaseMutation
    argument :custom_grade_status_id, ID, required: false, default_value: nil
    argument :enrollment_id, ID, required: true
    argument :grading_period_id, ID, required: false, default_value: nil
    field :grades, Types::GradesType, null: true

    def resolve(input:)
      raise GraphQL::ExecutionError, "custom gradebook statuses feature flag is disabled" unless Account.site_admin.feature_enabled?(:custom_gradebook_statuses)

      score = score(input:)
      unless score.grants_right?(current_user, session, :update_custom_status)
        raise GraphQL::ExecutionError, I18n.t("Insufficient permissions")
      end

      enrollment = Enrollment.find_by(id: input[:enrollment_id])
      custom_grade_status = get_custom_grade_status(input:)
      grading_period_id = input[:grading_period_id]

      updated_score = enrollment.update_override_status(custom_grade_status:, grading_period_id:)
      InstStatsd::Statsd.distributed_increment("custom_grade_status.applied_to.final_grade")
      { grades: updated_score }
    rescue ActiveRecord::RecordNotFound => e
      raise GraphQL::ExecutionError, "#{e.model} not found"
    rescue ActiveRecord::RecordInvalid => e
      errors_for(e.record)
    end

    private

    def score(input:)

View on GitHub (pinned to 1c9f0bb801)