instructure/canvas-lms · error · InvalidDataError

Group " " has already appeared in this import

Error message

Group "%{guid}" has already appeared in this import

What it means

After a group is imported its outcome_import_id is stamped with the current import. If the same vendor_guid appears again within the same import batch, import_group detects model.outcome_import_id == outcome_import_id and raises this error to prevent processing the same group twice in one run. Each group must appear at most once per import.

Solutions

  1. Deduplicate rows by vendor_guid before running the import, keeping the last/most complete row.
  2. Remove the second occurrence and, if re-parenting was intended, do it in a separate later import.
  3. Fix the generator so a parent group is emitted only once even when referenced multiple times.

Example fix

// before
rows = [g(vendor_guid: 'g1'), g(vendor_guid: 'g1')]
// after
rows = rows.uniq { |r| r[:vendor_guid] }
Defensive patterns

Strategy: validation

Validate before calling

guids = rows.select { |r| r[:object_type] == 'group' }.map { |r| r[:vendor_guid] }
raise ArgumentError, "duplicate group rows" if guids.uniq.size != guids.size

Try / catch

begin
  importer.import_object(row)
rescue Outcomes::Import::InvalidDataError => e
  skipped << {vendor_guid: row[:vendor_guid], error: e.message}
end

Prevention

When it happens

Trigger: A CSV/JSON import containing two rows with object_type 'group' and identical vendor_guid; the same group guid listed both as a definition and later as a re-parent update in the same file.

Common situations: Merged spreadsheets with duplicated rows; concatenating two export files that share guids; generator bugs emitting a group each time it is referenced as a parent.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/3aa3a7bc41f2bd1f. Report an issue: GitHub.

Appendix: source

Thrown at lib/outcomes/import.rb:121

        end
      end

      model = find_prior_group(group, group_context)
      unless model.context == group_context
        raise InvalidDataError, I18n.t(
          "Group with ID %{guid} already exists in another unrelated course or account (%{name})",
          guid: group[:vendor_guid],
          name: model.context.name
        )
      end

      parents = find_parents(group, group_context, model:)
      raise InvalidDataError, I18n.t("An outcome group can only have one parent") if parents.length > 1

      parent = parents.first

      if model.outcome_import_id == outcome_import_id
        raise InvalidDataError, I18n.t(
          'Group "%{guid}" has already appeared in this import',
          guid: group[:vendor_guid]
        )
      end
      model.vendor_guid = group[:vendor_guid]
      model.title = group[:title]
      model.description = group[:description] || ""
      model.workflow_state = group[:workflow_state].presence || "active"
      model.learning_outcome_group = parent
      model.outcome_import_id = outcome_import_id
      model.save!

      if model.workflow_state == "deleted"
        model.destroy!
      end

      model
    end

View on GitHub (pinned to 1c9f0bb801)