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

category has reached the maximum number of tags

Error message

category has reached the maximum number of tags

What it means

The mutation enforces a per-category cap on active tags, read from DynamicSettings (consul) under institutional_tags/max_tags_per_category with a fallback of 50. If the count of active tags in the category is >= max_tags it raises this GraphQL::ExecutionError instead of creating another tag.

Solutions

  1. Delete/deactivate unneeded tags in the category, then retry.
  2. Raise the cap in consul: set institutional_tags/max_tags_per_category to a higher value (or the account's DynamicSettings override).
  3. Move new tags to a different or new category.
  4. If the cap seems wrong, verify DynamicSettings.find('institutional_tags')['max_tags_per_category'] resolves as expected (failsafe nil path falls back to 50).

Example fix

// before
active tags in category = 50 (cap 50) -> raise
// after (consul)
{ "institutional_tags": { "max_tags_per_category": "200" } } // then retry mutation
Defensive patterns

Strategy: validation

Validate before calling

# pre-flight count check
max = DynamicSettings.find('institutional_tags')['max_tags_per_category', failsafe: nil]&.to_i || 50
if category.institutional_tags.where(workflow_state: 'active').count >= max
  raise "category #{category.id} at cap (#{max})"
end

Type guard

function categoryHasTagCapacity(category, activeTagCount, max = 50) {
  return activeTagCount < max;
}

Try / catch

try {
  await createInstitutionalTag({ variables })
} catch (e) {
  if (e.message.includes('maximum number of tags')) {
    // deactivate old tags or create/use another category
  }
}

Prevention

When it happens

Trigger: createInstitutionalTag on a category whose active institutional_tags count has reached the configured maximum (from consul DynamicSettings 'institutional_tags' key, default 50).

Common situations: Bulk-importing tags into a pre-filled category; default 50 cap hit because the consul key is absent; migrations/import scripts creating tags in a loop; test environments where the cap was tuned low.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at app/graphql/mutations/create_institutional_tag.rb:44

             ID,
             required: true,
             prepare: GraphQLHelpers.relay_or_legacy_id_prepare_func("InstitutionalTagCategory")
    argument :description, String, required: true
    argument :name,        String, required: true

    field :institutional_tag, Types::InstitutionalTagType, null: true

    def resolve(input:)
      root_account = context[:domain_root_account]
      raise GraphQL::ExecutionError, "feature flag is disabled" unless root_account.feature_enabled?(:institutional_tags)
      raise GraphQL::ExecutionError, "not authorized" unless root_account.grants_right?(current_user, session, :manage_institutional_tags_create)

      category = root_account.institutional_tag_categories.where(workflow_state: "active").find_by(id: input[:category_id])
      raise GraphQL::ExecutionError, "not found" unless category

      max_tags = DynamicSettings.find("institutional_tags")["max_tags_per_category", failsafe: nil]&.to_i || 50
      if category.institutional_tags.where(workflow_state: "active").count >= max_tags
        raise GraphQL::ExecutionError, "category has reached the maximum number of tags"
      end

      tag = category.institutional_tags.new(
        name: input[:name],
        description: input[:description],
        root_account:
      )

      if tag.save
        { institutional_tag: tag }
      else
        errors_for(tag)
      end
    rescue ActiveRecord::RecordInvalid
      errors_for(tag)
    rescue ActiveRecord::RecordNotFound
      raise GraphQL::ExecutionError, "not found"
    end

View on GitHub (pinned to 1c9f0bb801)