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.

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)

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.