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

  1. Ensure old_id and old_integration_id point to the same record — or supply only one of them.
  2. Regenerate the CSV from current data so both identifiers are in sync.
  3. 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

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


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)