{"record":{"id":"ad9a7e5869ad8996","repo":"instructure/canvas-lms","slug":"parent-group-not-found-in-this-context","errorCode":null,"errorMessage":"Parent group not found in this context","messagePattern":"Parent group not found in this context","errorType":"exception","errorClass":"GraphQL::ExecutionError","httpStatus":null,"severity":"warning","filePath":"app/graphql/mutations/update_learning_outcome_group.rb","lineNumber":59,"sourceCode":"        raise GraphQL::ExecutionError, I18n.t(\"Could not update parent group\") unless new_parent_group.adopt_outcome_group(@outcome_group)\n      end\n      { learning_outcome_group: @outcome_group }\n    else\n      errors_for(@outcome_group)\n    end\n  end\n\n  private\n\n  def get_group(id)\n    LearningOutcomeGroup.active.find_by(id:).tap do |group|\n      raise GraphQL::ExecutionError, I18n.t(\"Group not found\") unless group\n    end\n  end\n\n  def get_parent_group(id)\n    LearningOutcomeGroup.for_context(@outcome_group.context).active.find_by(id:).tap do |group|\n      raise GraphQL::ExecutionError, I18n.t(\"Parent group not found in this context\") unless group\n    end\n  end\n\n  def check_user_permissions\n    raise GraphQL::ExecutionError, I18n.t(\"Insufficient permissions\") unless can_manage_outcomes\n  end\n\n  def can_manage_outcomes\n    if @outcome_group.context\n      @outcome_group.context.grants_right?(current_user, session, :manage_outcomes)\n    else\n      Account.site_admin.grants_right?(current_user, session, :manage_global_outcomes)\n    end\n  end\n\n  def attributes(input)\n    input.to_h.slice(:title, :description, :vendor_guid)\n  end","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/app/graphql/mutations/update_learning_outcome_group.rb#L41-L77","documentation":"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).","triggerScenarios":"Passing parent_outcome_group_id that points to a group in a different account/course, a soft-deleted group, or a nonexistent id.","commonSituations":"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.","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."],"exampleFix":"// before\nupdateLearningOutcomeGroup(input: {id: \"5\", parentOutcomeGroupId: \"31\"}) // 31 is in another course\n// after\nupdateLearningOutcomeGroup(input: {id: \"5\", parentOutcomeGroupId: \"8\"}) // 8 is in the same context","handlingStrategy":"validation","validationCode":"const parents = await gql(FETCH_OUTCOME_GROUPS_FOR_CONTEXT, { contextId });\nconst valid = parents.outcomeGroups.some(g => String(g.id) === String(parentId));\nif (!valid) throw new Error('parent group not in this context');","typeGuard":"function isSameContext(parent, ctxId) { return parent?.contextId != null && String(parent.contextId) === String(ctxId); }","tryCatchPattern":"try {\n  await gql(UPDATE_LEARNING_OUTCOME_GROUP, { id, parentOutcomeGroupId: parentId });\n} catch (e) {\n  if (e.message === 'Parent group not found in this context') { /* offer only in-context parents */ }\n  else throw e;\n}","preventionTips":["Only offer parent options fetched from the same context","Exclude deleted/inactive groups from parent pickers","Don't copy parent ids across accounts/courses"],"tags":["graphql","outcome-groups","context-scope","record-not-found"],"backgroundTag":"record-not-found","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}