instructure/canvas-lms · error · InvalidDataError
Outcome " " has already appeared in this import
Error message
Outcome "%{guid}" has already appeared in this import What it means
Raised when import_outcome finds a prior outcome (by vendor_guid) whose outcome_import_id already equals the current import's id, meaning the same vendor_guid row has been processed twice within one outcome import. The library treats duplicate rows in a single import as data corruption, since a guid must uniquely identify an outcome per import run.
Solutions
- Deduplicate the import file so each vendor_guid appears only once.
- If both rows are intentional updates, merge their fields into one row keyed by the single vendor_guid.
- Fix the generating export/script that emitted the duplicate guid.
Example fix
// before: rows [{vendor_guid:'A',...},{vendor_guid:'A',...}]
// after: merge duplicates
{
"vendor_guid": "A",
"title": "merged title",
"ratings": [/* merged ratings */]
} Defensive patterns
Strategy: validation
Validate before calling
// Ruby: dedupe rows by vendor_guid before upload
guids = rows.map { |r| r[:vendor_guid] }
raise 'duplicate guids' if guids.uniq.size != guids.size
rows.uniq_by { |r| r[:vendor_guid] } Try / catch
begin
importer.import_object(...)
rescue Outcomes::Import::InvalidDataError => e
raise unless e.message.include?('already appeared in this import')
# drop later duplicate rows and re-queue the import
end Prevention
- Deduplicate import files on vendor_guid before creating the outcome import.
- Never merge exports from multiple sources without re-keying guids.
- Make retry logic idempotent at the file level, not per row.
When it happens
Trigger: An outcome import file (CSV/JSON) contains two rows with the same vendor_guid; import_outcome checks model.outcome_import_id == outcome_import_id at lib/outcomes/import.rb:167.
Common situations: Manually merged or concatenated outcome export files; CSV rows duplicated by a copy/paste mistake; a script that retries rows without deduplicating before upload.
Related errors
- Outcome with ID already exists in another unrelated course…
- Cannot modify outcome from another context
- Cyclic reference detected when importing
- Database error ( )
- Error importing outcomes
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/29073adb96faafc9.
Report an issue: GitHub.
Appendix: source
Thrown at lib/outcomes/import.rb:167
)
end
model = find_prior_outcome(outcome)
model.context = context if model.new_record?
unless child_context?(context, of: model.context)
raise InvalidDataError, I18n.t(
"Outcome with ID %{guid} already exists in another unrelated course or account (%{name})",
guid: outcome[:vendor_guid],
name: model.context.name
)
end
allow_indirect = outcome.key?(:course_id)
parents = find_parents(outcome, context, allow_indirect:)
if model.outcome_import_id == outcome_import_id
raise InvalidDataError, I18n.t(
'Outcome "%{guid}" has already appeared in this import',
guid: outcome[:vendor_guid]
)
end
model.vendor_guid = outcome[:vendor_guid]
model.title = outcome[:title]
model.description = infer_nil_value(model, :description, outcome)
model.display_name = infer_nil_value(model, :display_name, outcome)
model.calculation_method = outcome[:calculation_method].presence || model.default_calculation_method
model.calculation_int = outcome[:calculation_int].presence || model.default_calculation_int
# let removing the outcome_links content tags delete the underlying outcome
model.workflow_state = "active" unless outcome[:workflow_state] == "deleted"
prior_rubric = model.rubric_criterion || {}
changed = ->(k) { outcome[k].present? && outcome[k] != prior_rubric[k] }
rubric_change = changed.call(:ratings) || changed.call(:mastery_points)
model.rubric_criterion = create_rubric(outcome[:ratings], outcome[:mastery_points]) if rubric_changeView on GitHub (pinned to 1c9f0bb801)