instructure/canvas-lms · error · InvalidDataError

Outcome group with canvas id

Error message

Outcome group with canvas id %{id} not found

What it means

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.

Solutions

  1. Confirm the group id exists in the target context and fix the canvas_group guid.
  2. If the group was deleted, import the group definition (full row with title etc.) instead of referencing the id.
  3. Import into the context that actually owns the referenced group.

Example fix

// before
"vendor_guid": "canvas_group:888"  // deleted
// after: provide the full group definition so it can be created
{
  "vendor_guid": "group-my-guid",
  "title": "My Group"
}
Defensive patterns

Strategy: validation

Validate before calling

// Ruby: check group existence AND context before import
if (m = /canvas_group:(\d+)/.match(guid))
  g = LearningOutcomeGroup.find_by(id: m[1])
  raise 'missing or wrong-context group' unless g && g.context == target_context
end

Try / catch

begin
  importer.import_object(...)
rescue Outcomes::Import::InvalidDataError => e
  raise unless e.message.include?('Outcome group with canvas id')
  # provide a full group definition instead of the id reference
end

Prevention

When it happens

Trigger: 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.

Common situations: 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.

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

Appendix: source

Thrown at lib/outcomes/import.rb:271

        return prior if prior

        LearningOutcome.new(vendor_guid:)
      end
    end

    def find_prior_group(group, group_context)
      vendor_guid = group[:vendor_guid]
      prior = LearningOutcomeGroup.where(context: group_context).where(vendor_guid:).active_first.first
      return prior if prior

      match = /canvas_outcome_group:(\d+)/.match(vendor_guid)
      if match
        canvas_id = match[1]
        begin
          by_id = LearningOutcomeGroup.find(canvas_id)
          return by_id if by_id.context == group_context
        rescue ActiveRecord::RecordNotFound
          raise InvalidDataError, I18n.t(
            "Outcome group with canvas id %{id} not found",
            id: group[:canvas_id]
          )
        end
      end

      LearningOutcomeGroup.new(vendor_guid:, context: group_context)
    end

    def create_rubric(ratings, mastery_points)
      rubric = {}
      rubric[:enable] = true
      rubric[:mastery_points] = mastery_points
      rubric[:ratings] = ratings.map.with_index { |v, i| [i, v] }.to_h
      rubric
    end

    def root_parent(given_context)

View on GitHub (pinned to 1c9f0bb801)