{"record":{"id":"6b8f242eea11c396","repo":"spree/spree","slug":"email-is-required","errorCode":null,"errorMessage":"Email is required","messagePattern":"Email is required","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"spree/core/app/services/spree/imports/row_processors/customer.rb","lineNumber":17,"sourceCode":"module Spree\n  module Imports\n    module RowProcessors\n      class Customer < Base\n        def process!\n          user = find_or_initialize_user\n          assign_user_attributes(user)\n          assign_address(user) if address_fields_present?\n          user.save!\n          user\n        end\n\n        private\n\n        def find_or_initialize_user\n          email = attributes['email'].to_s.strip.downcase\n          raise ArgumentError, 'Email is required' if email.blank?\n\n          Spree.customer_class.find_or_initialize_by(email: email)\n        end\n\n        def assign_user_attributes(user)\n          user.first_name = attributes['first_name'].strip if attributes['first_name'].present?\n          user.last_name = attributes['last_name'].strip if attributes['last_name'].present?\n          user.phone = attributes['phone'].strip if attributes['phone'].present?\n          user.accepts_email_marketing = to_boolean(attributes['accepts_email_marketing']) if attributes['accepts_email_marketing'].present?\n          user.tag_list = attributes['tags'] if attributes['tags'].present?\n\n          if user.new_record?\n            password = SecureRandom.hex(16)\n            user.password = password\n            user.password_confirmation = password\n          end\n        end\n","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/spree/spree/blob/06bf66a8684b9de03210bbb2ddc8c1f5ba522fa2/spree/core/app/services/spree/imports/row_processors/customer.rb#L1-L35","documentation":"Spree::Imports::RowProcessors::Customer#process! raises ArgumentError 'Email is required' when a customer-import CSV row has no usable email (blank after strip). Email is the find_or_initialize_by key on Spree.customer_class, so a row without it cannot identify or create a customer and the row is rejected before any attribute is assigned.","triggerScenarios":"Running a customers CSV import where the 'email' column is absent from the header, empty on some row, or contains only whitespace. The processor strips and downcases attributes['email'] and raises when the result is blank.","commonSituations":"Exported file with a renamed or mistyped header ('Email', 'e-mail', 'email '), spreadsheet saving blank cells as empty strings, UTF-8 BOM shifting the first header, or assuming email is optional because the storefront allows guest data without it.","solutions":["Open the CSV and confirm a header column named exactly 'email' exists.","Fill in or remove every row whose email cell is empty or whitespace-only.","Re-save the file as plain UTF-8 without BOM and strip stray whitespace from headers.","Re-run the import; row-level failures are reported per row, so previously imported rows are not lost."],"exampleFix":"# before — customers.csv\nfirst_name,last_name\nAda,Lovelace\n\n# after\nemail,first_name,last_name\nada@example.com,Ada,Lovelace","handlingStrategy":"validation","validationCode":"# before submitting a customers import, reject/repair rows without email\nrequire 'csv'\n\ninvalid = []\nCSV.table(csv_path, converters: nil).each.with_index(2) do |row, line|\n  invalid << line if row[:email].to_s.strip.blank?\nend\nabort \"Rows without email: #{invalid.join(', ')}\" if invalid.any?","typeGuard":null,"tryCatchPattern":"begin\n  processor.process!\nrescue ArgumentError => e\n  # per-row failure: record line + message, keep importing the rest\n  import_row.update!(status: 'failed', error_message: e.message)\nend","preventionTips":["Give merchants a downloadable CSV template with the email header pre-filled.","Validate headers and required columns client-side (dashboard import wizard) before upload.","Treat import failures as row-level: collect and surface line numbers instead of aborting the file."],"tags":["csv-import","customers","validation","spree-core"],"backgroundTag":"required-csv-column-missing","analyzedSha":"06bf66a8684b9de03210bbb2ddc8c1f5ba522fa2","analyzedAt":"2026-08-21T14:59:48.125Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}