we-promise/sure · warning · BrexItem::AccountFlow::AccountNotFoundError

BrexItem::AccountFlow::AccountNotFoundError

Error message

BrexItem::AccountFlow::AccountNotFoundError

What it means

Raised by BrexItem::AccountFlow#link_existing_account! as AccountNotFoundError when brex_account_id is absent from indexed_accounts, the index built from the provider's get_accounts (served from a 5-minute Rails cache keyed brex_accounts_<family>_<item>). The id must exist in the currently fetched (or cached) Brex account list at link time.

Solutions

  1. Refresh the account list and retry with an id returned by the current flow (select_existing_account_result / preload_payload) — pass the provider account id, not the local DB id.
  2. Expire the stale cache: Rails.cache.delete(BrexItem::AccountFlow.cache_key(family, brex_item)) (TTL is 5 minutes, so waiting also works).
  3. Confirm the correct Brex connection (brex_item) is selected when the family has several — ids do not transfer between them.
  4. Rescue AccountNotFoundError when calling link_existing_account! directly and re-render the picker with fresh data.

Example fix

# before
flow.link_existing_account!(account: account, brex_account_id: params[:brex_account_id])

# after — validate against the live list, and handle the miss
begin
  flow.link_existing_account!(account: account, brex_account_id: params[:brex_account_id])
rescue BrexItem::AccountFlow::AccountNotFoundError
  Rails.cache.delete(BrexItem::AccountFlow.cache_key(family, flow.brex_item))
  redirect_to select_accounts_path, alert: "That Brex account is no longer available — pick again."
end
Defensive patterns

Strategy: try-catch

Validate before calling

# expire stale cache so the id list is fresh before linking
Rails.cache.delete(BrexItem::AccountFlow.cache_key(family, brex_item))
flow = BrexItem::AccountFlow.new(family: family, brex_item: brex_item)

Try / catch

begin
  flow.link_existing_account!(account: account, brex_account_id: id)
rescue BrexItem::AccountFlow::AccountNotFoundError
  redirect_to select_accounts_path, alert: "That Brex account is no longer available — choose again."
end

Prevention

When it happens

Trigger: POSTing link_existing_account with a brex_account_id that is not in the list: a stale page rendered from cache before the account was closed at Brex or before the token switched to a different Brex organization; a hand-edited id; race where another flow expired/rewrote the cache between render and submit (app/models/brex_item/account_flow.rb:205-206).

Common situations: User keeps an old tab open, closes the account at Brex, then submits; switching between multiple Brex connections (cache is per family+item); id passed as the internal BrexAccount record id instead of the provider's account id.

Related errors


AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21). Data as JSON: /api/errors/042ef9e0360cec9e. Report an issue: GitHub.

Appendix: source

Thrown at app/models/brex_item/account_flow.rb:206

        )

        AccountProvider.create!(account: account, provider: brex_account)
        created_accounts << account
      end
    end

    brex_item.sync_later if created_accounts.any?

    LinkAccountsResult.new(
      created_accounts: created_accounts,
      already_linked_names: already_linked_names,
      invalid_account_ids: invalid_account_ids
    )
  end

  def link_existing_account!(account:, brex_account_id:)
    account_data = indexed_accounts[brex_account_id.to_s]
    raise AccountNotFoundError unless account_data

    account_name = BrexAccount.name_for(account_data)
    raise InvalidAccountNameError if account_name.blank?

    brex_account = nil

    ActiveRecord::Base.transaction do
      brex_account = upsert_brex_account!(brex_account_id, account_data)
      raise AccountAlreadyLinkedError if brex_account.account_provider.present?

      AccountProvider.create!(account: account, provider: brex_account)
    end

    brex_item.sync_later

    brex_account
  end

View on GitHub (pinned to e69894adb9)