instructure/canvas-lms · error · ImportError
An observer referenced a non-existent user #
Error message
An observer referenced a non-existent user #{observer_id} What it means
Referential-integrity error in UserObserverImporter::Work#process_user_observer raised when observer_id is present but no matching user exists in the root account (not previously imported and not resolvable). The observer link cannot be created, so the row fails.
Solutions
- Import the observer user before the user_observers file
- Verify the observer_id matches the user's sis_source_id
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at lib/sis/user_observer_importer.rb:64 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/355ed0730ab4374a.
Report an issue: GitHub.
Appendix: source
Thrown at lib/sis/user_observer_importer.rb:64
def initialize(batch, root_account, logger)
@batch = batch
@root_account = root_account
@logger = logger
@success_count = 0
@users_to_update_account_associations = Set.new
@user_observers_to_update_sis_batch_ids = []
end
def process_user_observer(observer_id, student_id, status)
raise ImportError, "No observer_id given for a user observer" if observer_id.blank?
raise ImportError, "No user_id given for a user observer" if student_id.blank?
raise ImportError, "Can't observe yourself user #{student_id}" if student_id == observer_id
raise ImportError, "Improper status \"#{status}\" for a user_observer" unless /\A(active|deleted)\z/i.match?(status)
return if @batch.skip_deletes? && status =~ /deleted/i
o_pseudo = @root_account.pseudonyms.active.find_by(sis_user_id: observer_id)
raise ImportError, "An observer referenced a non-existent user #{observer_id}" unless o_pseudo
s_pseudo = @root_account.pseudonyms.active.find_by(sis_user_id: student_id)
raise ImportError, "A student referenced a non-existent user #{student_id}" unless s_pseudo
observer = o_pseudo.user
student = s_pseudo.user
raise ImportError, "Can't observe yourself user #{student_id}" if observer == student
add_remove_observer(observer, student, observer_id, student_id, status)
end
def add_remove_observer(observer, student, observer_id, student_id, status)
case status.downcase
when "active"
check_observer_notification_settings(observer)
user_observer = UserObservationLink.create_or_restore(observer:, student:, root_account: @root_account)
when "deleted"
user_observer = observer.as_observer_observation_links.for_root_accounts(@root_account).find_by(user_id: student)View on GitHub (pinned to 1c9f0bb801)