{"record":{"id":"4e3f759c1872d675","repo":"we-promise/sure","slug":"brex-transaction-missing-required-field-id","errorCode":null,"errorMessage":"Brex transaction missing required field 'id'","messagePattern":"Brex transaction missing required field 'id'","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"app/models/brex_entry/processor.rb","lineNumber":62,"sourceCode":"\n  private\n    attr_reader :brex_transaction, :brex_account\n\n    def import_adapter\n      @import_adapter ||= Account::ProviderImportAdapter.new(account)\n    end\n\n    def account\n      @account ||= brex_account.current_account\n    end\n\n    def data\n      @data ||= brex_transaction.with_indifferent_access\n    end\n\n    def external_id\n      id = data[:id].presence\n      raise ArgumentError, \"Brex transaction missing required field 'id'\" unless id\n\n      \"brex_#{id}\"\n    end\n\n    def safe_external_id\n      external_id\n    rescue ArgumentError\n      \"brex_unknown\"\n    end\n\n    def name\n      data[:description].presence ||\n        merchant_payload[:raw_descriptor].presence ||\n        merchant_payload[:name].presence ||\n        I18n.t(\"brex_items.entries.default_name\")\n    end\n\n    def notes","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/we-promise/sure/blob/e69894adb92547273377398c15f45c979cd9416a/app/models/brex_entry/processor.rb#L44-L80","documentation":"Raised by BrexEntry::Processor#external_id (ArgumentError) when the Brex transaction payload's :id is nil or blank. The id is mandatory because it builds the deduplication key \"brex_#{id}\" passed to import_transaction. process() logs it and re-raises, so one malformed transaction aborts the sync batch unless the caller filters it.","triggerScenarios":"BinanceItem::Importer-style loop hands the processor a transaction hash lacking \"id\" — e.g. a Brex webhook body or test fixture shaped differently, an upstream API change renaming the field, an empty-string id, or a payload accidentally wrapped one level too deep (data[:id] nil because the hash is nested under \"transaction\").","commonSituations":"VCR fixtures recorded from a different API version; sandbox payloads with null ids; a payload-shape refactor upstream; JSON where the array element is { \"transaction\" => {...} } rather than the transaction itself.","solutions":["Inspect the failing payload (data) and confirm the id key — log data.keys for the failing transaction to catch shape drift immediately.","Filter before processing: skip (and log) entries whose [:id] is blank so one bad record cannot kill the batch.","If the shape changed upstream (renamed/nested field), update the extraction in BrexEntry::Processor or map it before enqueueing.","Fix fixtures/tests to always include a realistic Brex transaction id."],"exampleFix":"# before\ntransactions.each { |tx| BrexEntry::Processor.new(tx, brex_account: ba).process }\n\n# after\ntransactions.each do |tx|\n  unless tx.with_indifferent_access[:id].present?\n    Rails.logger.warn(\"Skipping Brex transaction without id: #{tx.inspect}\")\n    next\n  end\n  BrexEntry::Processor.new(tx, brex_account: ba).process\nend","handlingStrategy":"validation","validationCode":"tx = transaction_payload.with_indifferent_access\nreturn :skipped unless tx[:id].present? # every Brex transaction must carry an id","typeGuard":"# Ruby\ndef processable_brex_tx?(payload)\n  payload.is_a?(Hash) && payload.with_indifferent_access[:id].present?\nend","tryCatchPattern":"begin\n  BrexEntry::Processor.new(tx, brex_account: ba).process\nrescue ArgumentError => e\n  raise unless e.message.include?(\"missing required field 'id'\")\n  Rails.logger.warn(\"Skipping Brex transaction without id: #{tx.inspect}\")\n  :skipped\nend","preventionTips":["Validate the id field at the queue boundary (webhook/importer entry) so malformed payloads are quarantined before processing.","Keep fixtures and VCR cassettes shaped like real Brex payloads, id included.","When Brex ships API changes, log data.keys on failures to catch renamed/nested id fields fast."],"tags":["brex","import","missing-field","payload-validation"],"backgroundTag":"missing-required-field","analyzedSha":"e69894adb92547273377398c15f45c979cd9416a","analyzedAt":"2026-08-21T18:22:41.165Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}