instructure/canvas-lms · error · GraphQL::ExecutionError
not found
Error message
not found
What it means
After flag and permission checks pass, updateInstitutionalTag looks up the tag scoped to root_account_id and workflow_state 'active' with find_by(id:). If no matching active tag exists, it raises GraphQL::ExecutionError "not found". Note this is a find_by nil check, not a rescued RecordNotFound.
Solutions
- Confirm the tag is active: InstitutionalTag.where(root_account_id:, workflow_state: 'active').find_by(id:) in console.
- If the tag is archived, use the archive-state mutation to undestroy it before editing.
- Verify the id belongs to the same root account the request resolves to.
- Refresh the tag list in the client to drop stale ids.
Example fix
// before
updateInstitutionalTag(input: { id: archivedTagId, name: "new" })
// after
updateInstitutionalTagArchivedState(input: { id: archivedTagId, archived: false })
updateInstitutionalTag(input: { id: archivedTagId, name: "new" }) Defensive patterns
Strategy: validation
Validate before calling
// fetch only active tags and ensure the id is among them
const tags = await fetchActiveInstitutionalTags(rootAccountId)
if (!tags.some(t => t.id === tagId)) throw new Error(`active tag ${tagId} not found`) Type guard
const isActiveTag = (t) => !!t && t.workflowState === 'active'
Try / catch
try {
await updateInstitutionalTag(input)
} catch (e) {
if (e.graphQLErrors?.some(g => g.message === 'not found')) {
await refreshTagList() // maybe archived or cross-account
} else { throw e }
} Prevention
- Only allow editing tags loaded from an active-tags query.
- Undestroy an archived tag first if it must be edited.
- Never reuse tag ids across accounts/environments.
When it happens
Trigger: Calling updateInstitutionalTag with an id that doesn't exist; the tag exists but is soft-deleted/archived (workflow_state != 'active'); the tag belongs to a different root account.
Common situations: Archiving a tag via updateInstitutionalTagArchivedState then trying to edit it with the plain update mutation; cross-tenant id reuse in multi-tenant setups; stale UI listing a deleted tag.
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/872582934baddd40.
Report an issue: GitHub.
Appendix: source
Thrown at app/graphql/mutations/update_institutional_tag.rb:44
ID,
required: false,
prepare: GraphQLHelpers.relay_or_legacy_id_prepare_func("InstitutionalTagCategory")
argument :description, String, required: false
argument :id,
ID,
required: true,
prepare: GraphQLHelpers.relay_or_legacy_id_prepare_func("InstitutionalTag")
argument :name, String, required: false
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_edit)
tag = InstitutionalTag.where(root_account_id: root_account.id, workflow_state: "active").find_by(id: input[:id])
raise GraphQL::ExecutionError, "not found" unless tag
attrs = {}
attrs[:name] = input[:name] if input.key?(:name)
attrs[:description] = input[:description] if input.key?(:description)
if input.key?(:category_id)
category = root_account.institutional_tag_categories.where(workflow_state: "active").find_by(id: input[:category_id])
raise GraphQL::ExecutionError, "not found" unless category
attrs[:category_id] = category.id
end
if tag.update(attrs)
{ institutional_tag: tag }
else
errors_for(tag)
end
rescue ActiveRecord::RecordInvalidView on GitHub (pinned to 1c9f0bb801)