instructure/canvas-lms · error · ImportError
An old_id, '# ', referenced a different # than the…
Error message
An old_id, '#{data_change.old_id}', referenced a different #{type} than the old_integration_id, '#{data_change.old_integration_id}' What it means
find_item_to_update raises this when both old_id and old_integration_id are present but they resolve to different records (old_item != old_int_item) — or one resolves to nil. The importer requires the two identifiers to agree on the same row; a disagreement means ambiguous or corrupted reference data, so the change is refused.
Solutions
- Ensure old_id and old_integration_id point to the same record — or supply only one of them.
- Regenerate the CSV from current data so both identifiers are in sync.
- Check which record each identifier currently resolves to and correct the mismatched one.
Example fix
// before: ids from different records user,U1,new-id,INT-OF-OTHER-USER // after user,U1,new-id,INT-OF-U1
Defensive patterns
Strategy: validation
Validate before calling
if dc.old_id.present? && dc.old_integration_id.present? a = scope.find_by(column => dc.old_id) b = scope.find_by(integration_id: dc.old_integration_id) raise ArgumentError, 'old_id and old_integration_id reference different records' unless a == b end process_change_sis_id(dc)
Try / catch
begin
process_change_sis_id(dc)
rescue SIS::ImportError => e
errors << e.message if e.message.include?('referenced a different')
end Prevention
- Supply only one of old_id / old_integration_id unless you can guarantee they resolve to the same row.
- Regenerate CSVs from current DB state rather than caching old exports.
- Reconcile integration_id assignments after any migration before re-keying.
When it happens
Trigger: A change_sis_id row where scope.find_by(sis_source_id => old_id) and scope.find_by(integration_id => old_integration_id) return different objects, or where one of the two lookups finds nothing (old_item == nil != old_int_item, or vice versa).
Common situations: Data drift where a record's integration_id was reassigned after the CSV was generated, copy-paste rows mixing identifiers from two records, or stale batch files referencing pre-migration data.
Related errors
- A new_id, '# ', referenced an existing # and the # with #…
- A new_integration_id, '#
- A student referenced a non-existent user #
- An old_id, '# ', referenced a non-existent # and was not…
- An old_integration_id, '#
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/156907dc280f6bae.
Report an issue: GitHub.
Appendix: source
Thrown at lib/sis/change_sis_id_importer.rb:142
raise ImportError, "Group categories should not have integration IDs."
end
check_new = details[:scope].where(column => data_change.new_id).exists? if data_change.new_id.present?
raise ImportError, "A new_id, '#{data_change.new_id}', referenced an existing #{type} and the #{type} with #{column} '#{data_change.old_id}' was not updated" if check_new
check_int = details[:scope].where(integration_id: data_change.new_integration_id).exists? if data_change.new_integration_id.present?
raise ImportError, "A new_integration_id, '#{data_change.new_integration_id}', referenced an existing #{type} and the #{type} with integration_id '#{data_change.old_integration_id}' was not updated" if check_int
end
def find_item_to_update(column, details, type, data_change)
if data_change.old_id.present?
old_item = details[:scope].find_by(column => data_change.old_id)
end
if data_change.old_integration_id.present?
old_int_item = details[:scope].find_by(integration_id: data_change.old_integration_id)
end
if data_change.old_id.present? && data_change.old_integration_id.present?
raise ImportError, "An old_id, '#{data_change.old_id}', referenced a different #{type} than the old_integration_id, '#{data_change.old_integration_id}'" unless old_item == old_int_item
return old_item
end
if data_change.old_id.present? && data_change.old_integration_id.blank?
raise ImportError, "An old_id, '#{data_change.old_id}', referenced a non-existent #{type} and was not changed." unless old_item
return old_item
end
if data_change.old_id.blank? && data_change.old_integration_id.present?
raise ImportError, "An old_integration_id, '#{data_change.old_integration_id}', referenced a non-existent #{type} and was not changed." unless old_int_item
old_int_item
end
end
end
end
end
View on GitHub (pinned to 1c9f0bb801)