{"record":{"id":"e09796915dbeecf9","repo":"we-promise/sure","slug":"row-row-number-account-account-name-is-no","errorCode":null,"errorMessage":"Row #{row_number}: Account '#{account_name}' is not mapped to an existing account. Please map this account in the import configuration.","messagePattern":"Row #(.+?): Account '#(.+?)' is not mapped to an existing account\\. Please map this account in the import configuration\\.","errorType":"validation","errorClass":"Import::MappingError","httpStatus":null,"severity":"error","filePath":"app/models/transaction_import.rb","lineNumber":24,"sourceCode":"      new_transactions = []\n      updated_entries = []\n      claimed_entry_ids = Set.new # Track entries we've already claimed in this import\n\n      rows.each_with_index do |row, index|\n        mapped_account = if account\n          account\n        else\n          mappings.accounts.mappable_for(row.account)\n        end\n\n        # Guard against nil account - this happens when an account name in CSV is not mapped\n        if mapped_account.nil?\n          row_number = index + 1\n          account_name = row.account.presence || \"(blank)\"\n          error_message = \"Row #{row_number}: Account '#{account_name}' is not mapped to an existing account. \" \\\n                         \"Please map this account in the import configuration.\"\n          errors.add(:base, error_message)\n          raise Import::MappingError, error_message\n        end\n\n        category = mappings.categories.mappable_for(row.category)\n        tags = row.tags_list.map { |tag| mappings.tags.mappable_for(tag) }.compact\n\n        # Use account's currency when no currency column was mapped in CSV, with family currency as fallback\n        effective_currency = currency_col_label.present? ? row.currency : (mapped_account.currency.presence || family.currency)\n\n        # Check for duplicate transactions using the adapter's deduplication logic\n        # Pass claimed_entry_ids to exclude entries we've already matched in this import\n        # This ensures identical rows within the CSV are all imported as separate transactions\n        adapter = Account::ProviderImportAdapter.new(mapped_account)\n        duplicate_entry = adapter.find_duplicate_transaction(\n          date: row.date_iso,\n          amount: row.signed_amount,\n          currency: effective_currency,\n          name: row.name,\n          exclude_entry_ids: claimed_entry_ids","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/we-promise/sure/blob/e69894adb92547273377398c15f45c979cd9416a/app/models/transaction_import.rb#L6-L42","documentation":"Raised as Import::MappingError by TransactionImport (app/models/transaction_import.rb:24) when a CSV row's account name resolves to no account: mappings.accounts.mappable_for(row.account) returns nil. Before raising, the code adds the same message to errors[:base] with the 1-based row number and the offending account name (or '(blank)'). This is the safety net for CSV imports where every row must be attributed to a real account before transactions can be created.","triggerScenarios":"Creating/running a TransactionImport whose CSV contains an account name that has no mapping configured: a renamed bank account, casing or whitespace differences between the CSV and the mapping, a blank account column with no default mapping, or mappings that were edited after the CSV was uploaded.","commonSituations":"Bank export uses 'Checking ••1234' while the mapping table has 'Checking'; CSV column order changed so the account column reads empty; the import configuration screen was submitted without mapping all distinct account names from the file.","solutions":["Open the import configuration and map every account name present in the CSV to an existing account, then retry the import.","Inspect the CSV around the reported row number and fix the account cell (typos, stray whitespace, wrong column mapped) — '(blank)' means the account cell is empty.","Pre-flight the file: list distinct row.account values and confirm each one has a mapping before starting the import.","If a mapping genuinely cannot exist, remove or correct those rows in the CSV; the import aborts atomically on the first unmapped row."],"exampleFix":"// before\nimport.create_transactions! # aborts: \"Row 12: Account 'Checking 1234' is not mapped...\"\n\n// after\nimport.csv_rows.each_with_index do |row, i|\n  next if import.mappings.accounts.mappable_for(row.account)\n  raise \"Row #{i + 1}: map '#{row.account}' before importing\"\nend\nimport.create_transactions!","handlingStrategy":"validation","validationCode":"names = import.csv_rows.map(&:account).compact.uniq\nunmapped = names.reject { |n| import.mappings.accounts.mappable_for(n) }\nfail \"Unmapped accounts: #{unmapped.join(', ')}\" if unmapped.any?","typeGuard":"row.account.present? && import.mappings.accounts.mappable_for(row.account).present?","tryCatchPattern":"begin\n  import.create_transactions!\nrescue Import::MappingError => e\n  # e.message already names the offending row + account; show import.errors[:base]\n  flash.now[:alert] = e.message\nend","preventionTips":["Run a pre-flight pass listing distinct CSV account names vs mappings before starting the import.","After uploading a CSV, always complete the mapping step for every detected account name.","Watch for '(blank)' in the message — it indicates an empty account cell or a wrongly mapped CSV column."],"tags":["rails","csv-import","transaction-import","mapping","data-validation"],"backgroundTag":"csv-import-mapping-missing","analyzedSha":"e69894adb92547273377398c15f45c979cd9416a","analyzedAt":"2026-08-21T18:22:41.165Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}