instructure/canvas-lms · warning · GraphQL::ExecutionError

Group not found

Error message

Group not found

What it means

UpdateLearningOutcomeGroup#get_group raises this when LearningOutcomeGroup.active.find_by(id:) returns nil for the group id supplied in the mutation. It signals the target group to update does not exist (or is not active).

Solutions

  1. Verify the id exists and is active: LearningOutcomeGroup.active.find_by(id: id) in console.
  2. Check the group's workflow_state — soft-deleted groups won't match the .active scope.
  3. Refresh the group id from the API instead of using a cached value.
  4. Confirm you are querying the correct shard/database.

Example fix

// before
updateLearningOutcomeGroup(input: {id: "999"}) { ... } // deleted group
// after
# const group = await fetchOutcomeGroup(id); if (!group) showNotFound();
updateLearningOutcomeGroup(input: {id: "12"}) { ... }
Defensive patterns

Strategy: validation

Validate before calling

const group = await gql(FETCH_OUTCOME_GROUP, { id });
if (!group?.learningOutcomeGroup) throw new Error(`group ${id} not found`);

Type guard

function groupExists(data) { return data?.learningOutcomeGroup != null; }

Try / catch

try {
  await gql(UPDATE_LEARNING_OUTCOME_GROUP, { id, ...attrs });
} catch (e) {
  if (e.message === 'Group not found') { /* remove stale item from UI list */ }
  else throw e;
}

Prevention

When it happens

Trigger: Calling updateLearningOutcomeGroup with input.id referencing a deleted/inactive group, a nonexistent id, or an id on a different shard.

Common situations: Group soft-deleted (workflow_state != active) so find_by(id:) with .active scope misses it; stale client cache; id from another environment; typo in the id.

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/6be9d6a28f9ca7ca. Report an issue: GitHub.

Appendix: source

Thrown at app/graphql/mutations/update_learning_outcome_group.rb:53

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

View on GitHub (pinned to 1c9f0bb801)