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

not found

Error message

not found

What it means

CreateInstitutionalTag looks up the tag category scoped to the root account and active workflow_state via find_by(id: input[:category_id]). If nothing matches, it raises this GraphQL::ExecutionError. This differs from the trailing RecordNotFound rescue: this is the pre-validation lookup failing silently (find_by returns nil).

Solutions

  1. Verify the category_id exists: root_account.institutional_tag_categories.find_by(id: ...) in console.
  2. Confirm the category's workflow_state is 'active' (not deleted/inactive).
  3. Check the ID is from the same root account; cross-account IDs will not be found.
  4. If using a GraphQL global ID, confirm the relay_or_legacy_id_prepare_func decodes it to the expected legacy id.
  5. Recreate/activate the category if it was deleted, then retry.

Example fix

// before
{ createInstitutionalTag(input: {categoryId: "99", name: "Tier", description: "..."}) } // category 99 inactive/absent
// after
const category = await fetchActiveCategory();
createInstitutionalTag({ variables: { categoryId: category.id, name: 'Tier', description: '...' } })
Defensive patterns

Strategy: validation

Validate before calling

# resolve the ID client-side first
const category = await gql(`query($id: ID!){ institutionalTagCategory(id:$id){ id workflowState } }`, { id: categoryId });
if (!category || category.workflowState !== 'active') throw new Error('category not found or inactive');

Type guard

function isActiveCategory(c) {
  return c != null && c.workflowState === 'active';
}

Try / catch

try {
  await createInstitutionalTag({ variables: { categoryId } })
} catch (e) {
  if (e.message === 'not found') { /* refresh category list, ask user to pick again */ }
}

Prevention

When it happens

Trigger: category_id does not exist; the category belongs to a different root account; the category has workflow_state other than 'active' (deleted/inactive); the relay/legacy ID preparation produced an unexpected id value.

Common situations: Passing an ID from another account or shard; querying a soft-deleted category; a client caching an old category ID after the category was deactivated; confusing legacy numeric IDs with relay global IDs (e.g. 'InstitutionalTagCategory-5' vs 5) if the prepare helper mismatches.

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/697f13e1aeedf94c. Report an issue: GitHub.

Appendix: source

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

module Mutations
  class CreateInstitutionalTag < BaseMutation
    argument :category_id,
             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

View on GitHub (pinned to 1c9f0bb801)