instructure/canvas-lms · error · ActionController::RoutingError
Not Found
Error message
Not Found
What it means
After passing argument validation, process_user_observer looks up the observer's pseudonym via @root_account.pseudonyms.active.find_by(sis_user_id: observer_id). If no active pseudonym with that sis_user_id exists on the root account, this ImportError is raised: the observer_id does not reference an existing, active user in this account.
Solutions
- Import the observer user first (users.csv) so an active pseudonym with that sis_user_id exists on the root account.
- Verify the observer_id matches the pseudonym's sis_user_id exactly and is on the same root account.
- Check the pseudonym was not deleted (workflow_state inactive); re-activate or re-import the user.
- If the observer's user_id vs sis_user_id distinction is the issue, use the correct identifier.
Example fix
// before: observer referenced before being imported # users.csv: (no OBS009 row) # user_observers.csv: STU001,OBS009,active -> ImportError // after: import observer first # users.csv: OBS009,parent@example.com,Parent,active # user_observers.csv: STU001,OBS009,active
Defensive patterns
Strategy: validation
Validate before calling
exists = root_account.pseudonyms.active.exists?(sis_user_id: observer_id) raise 'observer SIS ID not found on root account' unless exists
Try / catch
begin
importer.process_user_observer(obs_id, stu_id, status)
rescue SIS::Import::ImportError => e
logger.warn("observer #{obs_id} not found: #{e.message}")
end Prevention
- Order imports: users.csv before user_observers so referenced observers exist.
- Ensure all users are imported on the same root account as the observer associations.
- Verify IDs against sis_user_id exactly (not integration_id or login).
- Check that prior batches did not soft-delete the observer's pseudonym.
When it happens
Trigger: observer_id contains an SIS ID never imported on this root account; the observer's pseudonym was soft-deleted (inactive) or belongs to a different root account/subaccount; the ID differs by case or whitespace from the stored sis_user_id.
Common situations: Cross-account SIS imports where the observer was provisioned in another root account; observers deleted earlier in the same batch or previously via SIS; typos or stale IDs from a prior year's export; users whose integration_id was given instead of sis_user_id.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- A user did not pass validation
- Enrollment # doesn't exist
- # (user # , login # )
- A student referenced a non-existent user #
- An email did not pass validation
AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15).
Data as JSON: /api/errors/aa065df86aba6516.
Report an issue: GitHub.
Appendix: source
Thrown at app/controllers/application_controller.rb:3312
common_courses = courses.map do |course|
course_json(course, current_user, session, ["html_url"], false).merge({
roles: common_courses[course.id].map { |role| Enrollment.readable_type(role) }
})
end
common_groups = groups.map do |group|
group_json(group, current_user, session, include: ["html_url"]).merge({
# in the future groups will have more roles and we'll need soemthing similar to
# the roles.map above in courses
roles: [t("#group.memeber", "Member")]
})
end
common_courses + common_groups
end
def not_found
raise ActionController::RoutingError, "Not Found"
end
def set_js_rights(objtypes = nil)
objtypes ||= js_rights if respond_to?(:js_rights)
if objtypes
hash = {}
objtypes.each do |instance_symbol|
instance_name = instance_symbol.to_s
obj = instance_variable_get(:"@#{instance_name}")
policy = obj.check_policy(@current_user, session) unless obj.nil? || !obj.respond_to?(:check_policy)
hash[:"#{instance_name.upcase}_RIGHTS"] = ActiveSupport::HashWithIndifferentAccess[policy.map { |right| [right, true] }] unless policy.nil?
end
js_env hash
end
end
def set_js_wiki_data(opts = {})View on GitHub (pinned to 1c9f0bb801)