instructure/canvas-lms · error · ImportError

No name given for user

Error message

No name given for user

What it means

SisImports::ImportError raised by SIS::UserImporter#infer_user_name when a CSV user row provides no usable name source whatsoever. The importer tries, in order: full_name, first_name/last_name, prior_name, sortable_name, short_name, and finally login_id. If every one of those fields is blank there is nothing to name the user with, so the row is rejected rather than creating an anonymous User.

Solutions

  1. Add a full_name (or first_name/last_name) value to the offending CSV row; check user_row.user_id in the import error report to find it
  2. Ensure login_id is populated for the row — the importer falls back to it as the display name
  3. If updating an existing user, keep the name columns or rely on prior_name: do not blank them out on re-import
  4. Pre-validate the CSV before upload: reject rows where all name fields and login_id are blank

Example fix

// before (users.csv row)
user_id,status
1001,active

// after
user_id,full_name,status
1001,Jane Doe,active
Defensive patterns

Strategy: validation

Validate before calling

def row_has_name?(row)
  [row[:full_name], row[:first_name], row[:last_name],
   row[:sortable_name], row[:short_name], row[:login_id]]
    .any? { |v| v.is_a?(String) && v.strip.present? }
end
raise 'row missing all name fields' unless row_has_name?(csv_row)

Type guard

def present_str?(v) = v.is_a?(String) && !v.strip.empty?

Try / catch

begin
  importer.process_batch
rescue SisImports::ImportError => e
  next if e.message == 'No name given for user'
  raise
end

Prevention

When it happens

Trigger: A users.csv row processed via SIS batch import (process_batch -> new_user -> infer_user_name) where full_name, first_name, last_name, sortable_name, short_name, and login_id are all absent or empty strings. This happens for a brand-new user (no prior_name to inherit) with a login_id column that is empty or whitespace.

Common situations: Hand-edited or partially filled CSV templates where a row has only user_id and status filled in; downstream scripts that strip empty columns; export tools that write blank login_id when the authentication is external; renaming flows that removed the name columns while creating genuinely new users.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of instructure/canvas-lms@1c9f0bb801 (2026-09-15). Data as JSON: /api/errors/0de49c9a581b2ba7. Report an issue: GitHub.

Appendix: source

Thrown at lib/sis/user_importer.rb:107

      def any_left_to_process?
        !@batched_users.empty?
      end

      def infer_user_name(user_row, prior_name = nil)
        if user_row.full_name.present?
          user_row.full_name
        elsif user_row.first_name.present? || user_row.last_name.present?
          [user_row.first_name, user_row.last_name].join(" ")
        elsif prior_name.present?
          prior_name
        elsif user_row.sortable_name.present?
          user_row.sortable_name
        elsif user_row.short_name.present?
          user_row.short_name
        elsif user_row.login_id.present?
          user_row.login_id
        else
          raise ImportError, "No name given for user"
        end
      end

      def infer_sortable_name(user_row, prior_sortable_name = nil)
        if user_row.sortable_name.present?
          user_row.sortable_name
        elsif user_row.full_name.present?
          nil # force User model to infer sortable name from the full name
        elsif user_row.last_name.present? || user_row.first_name.present?
          [user_row.last_name, user_row.first_name].join(", ")
        else
          prior_sortable_name
        end
      end

      VALID_STATUSES = %w[active suspended deleted].freeze
      private_constant :VALID_STATUSES

View on GitHub (pinned to 1c9f0bb801)