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
- Verify the category_id exists: root_account.institutional_tag_categories.find_by(id: ...) in console.
- Confirm the category's workflow_state is 'active' (not deleted/inactive).
- Check the ID is from the same root account; cross-account IDs will not be found.
- If using a GraphQL global ID, confirm the relay_or_legacy_id_prepare_func decodes it to the expected legacy id.
- 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
- Always fetch category IDs from the same root account's query
- Filter categories by workflowState active before offering them in the UI
- Refresh cached category lists after deactivate/delete operations
- Ensure global vs legacy ID formats match the mutation's prepare helper
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::RecordInvalidView on GitHub (pinned to 1c9f0bb801)