{"record":{"id":"82e3c35d25f1d10c","repo":"instructure/canvas-lms","slug":"a-user-did-not-pass-validation-user-user-row-user-id-error","errorCode":null,"errorMessage":"A user did not pass validation (user: #{user_row.user_id}, error: #{pseudo.errors.full_messages.join(\", \")})","messagePattern":"A user did not pass validation \\(user: #(.+?), error: #(.+?)\\)","errorType":"validation","errorClass":"ImportError","httpStatus":null,"severity":"error","filePath":"lib/sis/user_importer.rb","lineNumber":477,"sourceCode":"          elsif user_row.email.present? && EmailAddressValidator.valid?(user_row.email) == false\n            message = \"The email address associated with user '#{user_row.user_id}' is invalid (email: '#{user_row.email}')\"\n            @messages << SisBatch.build_error(user_row.csv, message, sis_batch: @batch, row: user_row.lineno, row_info: user_row.row)\n            next\n          end\n\n          if pseudo.changed? || (Pseudonym.sis_stickiness_options[:clear_sis_stickiness] && pseudo[\"stuck_sis_fields\"].present?)\n            pseudo.sis_batch_id = user_row.sis_batch_id if user_row.sis_batch_id\n            pseudo.sis_batch_id = @batch.id if @batch\n            if pseudo.valid?\n              pseudo_changed = pseudo.changed?\n              if pseudo.save_without_broadcasting\n                record_sync_for(user) if pseudo_changed\n              end\n            else\n              msg = \"A user did not pass validation \"\n              msg += \"(\" + \"user: #{user_row.user_id}, error: \"\n              msg += pseudo.errors.full_messages.join(\", \") + \")\"\n              raise ImportError, msg\n            end\n          elsif @batch && pseudo.sis_batch_id != @batch.id\n            @pseudos_to_set_sis_batch_ids << pseudo.id\n          end\n          maybe_write_roll_back_data\n          if is_new_user_with_password_notification\n            cc.workflow_state = \"unconfirmed\"\n            should_sync_user = pseudo.changed? || cc.changed?\n            if pseudo.save_without_broadcasting\n              record_sync_for(user) if should_sync_user\n              if cc.save_without_broadcasting\n                pseudo.send_registration_notification!\n              end\n            end\n          end\n\n          @success_count += 1\n        end","sourceCodeStart":459,"sourceCodeEnd":495,"githubUrl":"https://github.com/instructure/canvas-lms/blob/1c9f0bb8013ed69c4f2efe11fd483025469b7e6c/lib/sis/user_importer.rb#L459-L495","documentation":"SisImports::ImportError raised in SIS::UserImporter#process_batch when the Pseudonym fails validation on the final save path (unlike the earlier per-attribute error, this reports ALL errors via pseudo.errors.full_messages joined with ', '). It is wrapped with the sis user_id for identification.","triggerScenarios":"During process_batch (called from add_user), when the pseudonym save for the row is invalid — e.g. login missing/blank after transformations, uniqueness failure, or invalid authentication provider settings — the else branch assembles 'A user did not pass validation (user: X, error: ...)' and raises ImportError.","commonSituations":"Rows where login_id becomes blank after trimming/casing rules; account-level policies (password complexity, login format) rejecting generated logins; uniqueness collisions not caught by the earlier single-error path; integration scripts writing inconsistent authentication_provider_id values.","solutions":["Parse the comma-separated error list in the message to see every failing attribute","Correct the login_id / authentication provider fields in users.csv for the reported user","Resolve uniqueness conflicts against existing pseudonyms in the root account","Review account login/password policy settings if previously-valid imports now fail"],"exampleFix":"// before (users.csv)\nuser_id,login_id\n1001,   \n\n// after\nuser_id,login_id\n1001,jdoe@school.edu","handlingStrategy":"try-catch","validationCode":"raise 'blank login_id' if row[:login_id].to_s.strip.empty?\nraise 'unknown auth provider' if row[:authentication_provider_id] &&\n  !account.authentication_providers.exists?(row[:authentication_provider_id])","typeGuard":null,"tryCatchPattern":"begin\n  importer.add_user(row)\nrescue SisImports::ImportError => e\n  raise unless e.message.start_with?('A user did not pass validation')\n  errors = e.message[/error: (.+)\\)$/, 1].to_s.split(', ')\n  logger.warn(\"Pseudonym invalid for #{row[:user_id]}: #{errors.inspect}\")\nend","preventionTips":["Pre-check login_id presence and format against account policies","Verify authentication_provider_id references an existing provider","Run imports against a staging account to surface pseudonym validation changes early"],"tags":["sis-import","activerecord-validation","pseudonym","ruby"],"backgroundTag":"schema-validation-failed","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"}