{"record":{"id":"e84d37baecc7a387","repo":"instructure/canvas-lms","slug":"an-old-id-data-change-old-id-referenced-a-non-existent-type","errorCode":null,"errorMessage":"An old_id, '#{data_change.old_id}', referenced a non-existent #{type} and was not changed.","messagePattern":"An old_id, '#(.+?)', referenced a non-existent #(.+?) and was not changed\\.","errorType":"exception","errorClass":"ImportError","httpStatus":null,"severity":"error","filePath":"lib/sis/change_sis_id_importer.rb","lineNumber":147,"sourceCode":"\n        check_int = details[:scope].where(integration_id: data_change.new_integration_id).exists? if data_change.new_integration_id.present?\n        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\n      end\n\n      def find_item_to_update(column, details, type, data_change)\n        if data_change.old_id.present?\n          old_item = details[:scope].find_by(column => data_change.old_id)\n        end\n        if data_change.old_integration_id.present?\n          old_int_item = details[:scope].find_by(integration_id: data_change.old_integration_id)\n        end\n        if data_change.old_id.present? && data_change.old_integration_id.present?\n          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\n\n          return old_item\n        end\n        if data_change.old_id.present? && data_change.old_integration_id.blank?\n          raise ImportError, \"An old_id, '#{data_change.old_id}', referenced a non-existent #{type} and was not changed.\" unless old_item\n\n          return old_item\n        end\n        if data_change.old_id.blank? && data_change.old_integration_id.present?\n          raise ImportError, \"An old_integration_id, '#{data_change.old_integration_id}', referenced a non-existent #{type} and was not changed.\" unless old_int_item\n\n          old_int_item\n        end\n      end\n    end\n  end\nend\n","sourceCodeStart":129,"sourceCodeEnd":160,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/lib/sis/change_sis_id_importer.rb#L129-L160","documentation":"find_item_to_update raises this when old_id is present, old_integration_id is blank, and no record of the given type matches scope.find_by(sis_source_id/sis_user_id => old_id). The importer cannot re-key a record it cannot find, so the row is rejected with the record left unchanged.","triggerScenarios":"change_sis_id row whose old_id does not match any existing sis_source_id (or sis_user_id for type=user) under the root account scope — wrong prefix, wrong account, record already deleted, or id already changed by a previous import.","commonSituations":"SIS id renamed earlier but CSV still carries the old value, importing into the wrong root_account, case-sensitivity/format mismatches, or referencing soft-deleted records outside the scope.","solutions":["Verify old_id against the current record (e.g. Course.where(root_account:..., sis_source_id: old_id)).","If the id was already changed, drop or update the stale row in the CSV.","Confirm the row is being imported into the same root_account that owns the record."],"exampleFix":"// before: id never existed\nuser,U-999,U-1000\n// after: use the real current sis id\nuser,U-100,U-1000","handlingStrategy":"validation","validationCode":"if dc.old_id.present? && dc.old_integration_id.blank?\n  unless scope_for(dc.type).where(sis_column_for(dc.type) => dc.old_id).exists?\n    raise ArgumentError, \"unknown #{dc.type} old_id #{dc.old_id}\"\n  end\nend\nprocess_change_sis_id(dc)","typeGuard":null,"tryCatchPattern":"begin\n  process_change_sis_id(dc)\nrescue SIS::ImportError => e\n  if e.message.include?('non-existent')\n    logger.warn(\"stale row for old_id=#{dc.old_id}: skipped\")\n  end\nend","preventionTips":["Regenerate change files from live data immediately before import.","Scope existence checks to the same root_account used by the import.","Mark previously applied renames so replays can be dropped."],"tags":["sis","ruby","import","not-found"],"backgroundTag":"record-not-found","analyzedSha":"1c9f0bb8013ed69c4f2efe11fd483025469b7e6c","analyzedAt":"2026-09-15T20:33:18.891Z","contentChangedAt":"2026-09-15T20:33:18.891Z","schemaVersion":2},"datasetVersion":"2026-09-23T02:17:17.105Z"}