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

  1. Ensure the parent group belongs to the same context as @outcome_group.context.
  2. Verify the parent is active: LearningOutcomeGroup.for_context(ctx).active.find_by(id:).
  3. Pick a parent group id within the same account/course hierarchy.
  4. 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

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


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)
  end

View on GitHub (pinned to 1c9f0bb801)