instructure/canvas-lms · error · GraphQL::ExecutionError
Could not update parent group
Error message
Could not update parent group
What it means
This error is raised in UpdateLearningOutcomeGroup#resolve when reparenting an outcome group fails: a new parent group was found, but adopt_outcome_group returned false, so the parent update could not be completed. It is a domain-level failure, not a validation error.
Solutions
- Check the new parent is not the group itself or one of its descendants (avoid cycles).
- Run the move manually in console (new_parent.adopt_outcome_group(group)) to see the underlying failure.
- Verify both groups' contexts are compatible (same account/course lineage).
- Retry after fixing hierarchy data, or move the group to a valid parent id.
Example fix
// before
updateLearningOutcomeGroup(input: {id: "5", parentOutcomeGroupId: "7"}) // 7 is a descendant of 5
// after
updateLearningOutcomeGroup(input: {id: "5", parentOutcomeGroupId: "2"}) // unrelated root-level group Defensive patterns
Strategy: validation
Validate before calling
function isValidReparent(group, newParentId) {
if (newParentId == null) return true;
if (String(newParentId) === String(group.id)) return false;
return !isDescendant(group, newParentId); // walk ancestors of new parent
} Try / catch
try {
await gql(UPDATE_LEARNING_OUTCOME_GROUP, { id, parentOutcomeGroupId: parentId });
} catch (e) {
if (e.message === 'Could not update parent group') { /* revert UI tree, offer valid parents */ }
else throw e;
} Prevention
- Never allow moving a group under itself or a descendant
- Keep group hierarchies within the same context
- Test deep/nested group trees before restructuring
When it happens
Trigger: Passing parent_outcome_group_id to updateLearningOutcomeGroup and the adopt step fails — typically because adopt_outcome_group hits a validation/constraint (e.g. cycle, depth, persistence error) while moving the group under the new parent.
Common situations: Attempting to move a group under its own descendant (cycle); outcome groups with conflicting contexts; DB constraint failures during the bulk update of affected groups; corrupt or deeply nested group trees.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Group not found
- Parent group not found in this context
- and cannot be used together
- and cannot be used together
- A course with that id does not exist
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/fb5ff522ccf4be2f.
Report an issue: GitHub.
Appendix: source
Thrown at app/graphql/mutations/update_learning_outcome_group.rb:41
argument :description, String, required: false
argument :id, ID, required: true, prepare: GraphQLHelpers.relay_or_legacy_id_prepare_func("LearningOutcomeGroup")
argument :parent_outcome_group_id, ID, required: false
argument :title, String, required: false
argument :vendor_guid, String, required: false
field :learning_outcome_group, Types::LearningOutcomeGroupType, null: true
def resolve(input:)
@outcome_group = get_group(input[:id])
check_user_permissions
@outcome_group.saving_user = current_user
if @outcome_group.update(attributes(input))
if input[:parent_outcome_group_id] && input[:parent_outcome_group_id] != @outcome_group.learning_outcome_group_id
new_parent_group = get_parent_group(input[:parent_outcome_group_id])
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 groupView on GitHub (pinned to 1c9f0bb801)