we-promise/sure · error · EnableBankingAccount::Processor::ProcessingError
Failed to set current balance: #{result.error}
Error message
Failed to set current balance: #{result.error} What it means
EnableBankingAccount::Processor raises ProcessingError when account.set_current_balance(balance) returns an unsuccessful Result. set_current_balance (Account::CurrentBalanceManager#set_current_balance) wraps ANY internal exception into Result(error: e.message) — typical root causes are reconciliation/valuation creation failures or the cache write account.update!(balance:) failing.
Source
Thrown at app/models/enable_banking_account/processor.rb:89
currency = parse_currency(enable_banking_account.currency) || account.currency || "EUR"
# Wrap both writes in a transaction so a failure on either rolls back both.
ActiveRecord::Base.transaction do
if account.accountable.present? && account.accountable.respond_to?(:available_credit=)
account.accountable.update!(available_credit: available_credit)
end
if skip_balance_update
account.update!(currency: currency)
else
account.update!(currency: currency, cash_balance: balance)
# Use set_current_balance to create a current_anchor valuation entry.
# This enables Balance::ReverseCalculator, which works backward from the
# bank-reported balance — eliminating spurious cash adjustment spikes.
result = account.set_current_balance(balance)
raise ProcessingError, "Failed to set current balance: #{result.error}" unless result.success?
end
end
# TODO: pass explicit window_start_date to sync_later to avoid full history recalculation on every sync
# Currently relies on set_current_balance's implicit sync trigger; window params would require refactor
end
# Interprets the reported credit card balance based on the
# treat_balance_as_available_credit flag.
# Returns [balance, available_credit, skip_balance_update].
def interpret_credit_card_balance(account, reported_balance)
if enable_banking_account.treat_balance_as_available_credit?
# In this mode the accountable's available_credit field holds the credit
# limit: the API-provided one, or a user-entered value when the API
# omits it. Writing the limit back (never the reported balance) keeps
# the field stable across syncs so a manual limit is never clobbered.
credit_limit = positive_credit_limit(enable_banking_account.credit_limit) ||
positive_credit_limit(account.accountable&.available_credit)View on GitHub (pinned to e69894adb9)
Solutions
- Read the interpolated result.error — it carries the original exception message from CurrentBalanceManager#set_current_balance
- Reproduce in console: account.set_current_balance(balance) on the failing account and inspect account.errors.full_messages and the raised cause
- Fix the underlying record state (currency, existing valuations, missing associations) that makes valuation/reconciliation creation fail
- For credit-card accounts, verify treat_balance_as_available_credit handling in interpret_credit_card_balance — the skip_balance_update path exists precisely to avoid bad balance writes
Defensive patterns
Strategy: try-catch
Validate before calling
result = account.set_current_balance(balance) result.success? # check before the processor raises; result.error carries the root cause
Try / catch
rescue EnableBankingAccount::Processor::ProcessingError => e; e.message embeds the CurrentBalanceManager error — log it with DebugLogEntry (category 'enable_banking') so partial syncs are diagnosable
Prevention
- Validate the account's base state (currency, family, existing valuations) before first sync
- Check set_current_balance's Result instead of assuming success
- For credit cards, verify treat_balance_as_available_credit so balances route to available_credit instead of failing cash writes
When it happens
Trigger: During an Enable Banking account import, after account.update!(currency:, cash_balance:), the current-balance manager fails: reconcile_balance or opening-balance delta adjustment raises (invalid amount/date, entry validation), or account.update! trips a validation; the manager converts it to a failed Result, and the processor re-raises as ProcessingError with that message.
Common situations: Bank-reported balances that violate entry validations; accounts in inconsistent state (missing currency/family, conflicting valuations); DB constraints on entries; unusual provider balance values on credit cards.
Related errors
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/a313f37e322788a6.
Report an issue: GitHub.