{"record":{"id":"e39413504b51c2cc","repo":"instructure/canvas-lms","slug":"outcome-group-with-canvas-id-id-not-found","errorCode":null,"errorMessage":"Outcome group with canvas id %{id} not found","messagePattern":"Outcome group with canvas id %(.+?) not found","errorType":"exception","errorClass":"InvalidDataError","httpStatus":null,"severity":"error","filePath":"lib/outcomes/import.rb","lineNumber":271,"sourceCode":"        return prior if prior\n\n        LearningOutcome.new(vendor_guid:)\n      end\n    end\n\n    def find_prior_group(group, group_context)\n      vendor_guid = group[:vendor_guid]\n      prior = LearningOutcomeGroup.where(context: group_context).where(vendor_guid:).active_first.first\n      return prior if prior\n\n      match = /canvas_outcome_group:(\\d+)/.match(vendor_guid)\n      if match\n        canvas_id = match[1]\n        begin\n          by_id = LearningOutcomeGroup.find(canvas_id)\n          return by_id if by_id.context == group_context\n        rescue ActiveRecord::RecordNotFound\n          raise InvalidDataError, I18n.t(\n            \"Outcome group with canvas id %{id} not found\",\n            id: group[:canvas_id]\n          )\n        end\n      end\n\n      LearningOutcomeGroup.new(vendor_guid:, context: group_context)\n    end\n\n    def create_rubric(ratings, mastery_points)\n      rubric = {}\n      rubric[:enable] = true\n      rubric[:mastery_points] = mastery_points\n      rubric[:ratings] = ratings.map.with_index { |v, i| [i, v] }.to_h\n      rubric\n    end\n\n    def root_parent(given_context)","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/lib/outcomes/import.rb#L253-L289","documentation":"find_prior_group resolves 'canvas_group:<id>' style vendor_guids for outcome groups via LearningOutcomeGroup.find. Beyond the record existing, the found group must belong to the importing group's context (by_id.context == group_context); a RecordNotFound is converted to this InvalidDataError. A group in another context falls through and is treated as not found, leading to different handling downstream.","triggerScenarios":"A group row whose guid is 'canvas_group:<id>' with no LearningOutcomeGroup of that id (deleted group, wrong shard), raised in find_prior_group (lib/outcomes/import.rb:271) via import_group.","commonSituations":"Importing a group export after the group was deleted; cross-instance migration where internal group ids don't match; importing into a different sub-account than the group's owner.","solutions":["Confirm the group id exists in the target context and fix the canvas_group guid.","If the group was deleted, import the group definition (full row with title etc.) instead of referencing the id.","Import into the context that actually owns the referenced group."],"exampleFix":"// before\n\"vendor_guid\": \"canvas_group:888\"  // deleted\n// after: provide the full group definition so it can be created\n{\n  \"vendor_guid\": \"group-my-guid\",\n  \"title\": \"My Group\"\n}","handlingStrategy":"validation","validationCode":"// Ruby: check group existence AND context before import\nif (m = /canvas_group:(\\d+)/.match(guid))\n  g = LearningOutcomeGroup.find_by(id: m[1])\n  raise 'missing or wrong-context group' unless g && g.context == target_context\nend","typeGuard":null,"tryCatchPattern":"begin\n  importer.import_object(...)\nrescue Outcomes::Import::InvalidDataError => e\n  raise unless e.message.include?('Outcome group with canvas id')\n  # provide a full group definition instead of the id reference\nend","preventionTips":["Import groups into the context that owns them.","Validate all canvas_group: ids right before each import run (groups may be deleted between runs).","Ship complete group definitions rather than id-only references in import files."],"tags":["outcomes","import","outcome-groups","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"}