instructure/canvas-lms · warning · GraphQL::ExecutionError
Parent group not found in this context
Error message
Parent group not found in this context
What it means
UpdateLearningOutcomeGroup#get_parent_group raises this when the requested parent group id does not resolve to an active LearningOutcomeGroup within the same context as the group being moved (LearningOutcomeGroup.for_context(@outcome_group.context).active.find_by(id:) returns nil).
Solutions
- Ensure the parent group belongs to the same context as @outcome_group.context.
- Verify the parent is active: LearningOutcomeGroup.for_context(ctx).active.find_by(id:).
- Pick a parent group id within the same account/course hierarchy.
- Re-fetch valid parent ids via the outcomeGroups query for the context.
Example fix
// before
updateLearningOutcomeGroup(input: {id: "5", parentOutcomeGroupId: "31"}) // 31 is in another course
// after
updateLearningOutcomeGroup(input: {id: "5", parentOutcomeGroupId: "8"}) // 8 is in the same context Defensive patterns
Strategy: validation
Validate before calling
const parents = await gql(FETCH_OUTCOME_GROUPS_FOR_CONTEXT, { contextId });
const valid = parents.outcomeGroups.some(g => String(g.id) === String(parentId));
if (!valid) throw new Error('parent group not in this context'); Type guard
function isSameContext(parent, ctxId) { return parent?.contextId != null && String(parent.contextId) === String(ctxId); } Try / catch
try {
await gql(UPDATE_LEARNING_OUTCOME_GROUP, { id, parentOutcomeGroupId: parentId });
} catch (e) {
if (e.message === 'Parent group not found in this context') { /* offer only in-context parents */ }
else throw e;
} Prevention
- Only offer parent options fetched from the same context
- Exclude deleted/inactive groups from parent pickers
- Don't copy parent ids across accounts/courses
When it happens
Trigger: Passing parent_outcome_group_id that points to a group in a different account/course, a soft-deleted group, or a nonexistent id.
Common situations: Moving a group under a parent from another course/account (cross-context); parent deleted recently; site-wide vs account-scoped group confusion; id copied from a different environment.
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
- Group not found
- A course with that id does not exist
- ActiveRecord::RecordNotFound
- Allocation rule not found
- An assignment with that id does not exist
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/ad9a7e5869ad8996.
Report an issue: GitHub.
Appendix: source
Thrown at app/graphql/mutations/update_learning_outcome_group.rb:59
raise GraphQL::ExecutionError, I18n.t("Could not update parent group") unless new_parent_group.adopt_outcome_group(@outcome_group)
end
{ learning_outcome_group: @outcome_group }
else
errors_for(@outcome_group)
end
end
private
def get_group(id)
LearningOutcomeGroup.active.find_by(id:).tap do |group|
raise GraphQL::ExecutionError, I18n.t("Group not found") unless group
end
end
def get_parent_group(id)
LearningOutcomeGroup.for_context(@outcome_group.context).active.find_by(id:).tap do |group|
raise GraphQL::ExecutionError, I18n.t("Parent group not found in this context") unless group
end
end
def check_user_permissions
raise GraphQL::ExecutionError, I18n.t("Insufficient permissions") unless can_manage_outcomes
end
def can_manage_outcomes
if @outcome_group.context
@outcome_group.context.grants_right?(current_user, session, :manage_outcomes)
else
Account.site_admin.grants_right?(current_user, session, :manage_global_outcomes)
end
end
def attributes(input)
input.to_h.slice(:title, :description, :vendor_guid)
endView on GitHub (pinned to 1c9f0bb801)