actualbudget/actual · error
ITEM_LOGIN_REQUIRED
ITEM_LOGIN_REQUIRED
Error message
ITEM_ERROR
What it means
Returned by getFailedSyncError for accounts whose bank_sync_status is 'reauth-required' with a non-simpleFin source (e.g. goCardless). It mirrors the Plaid-style ITEM_ERROR / ITEM_LOGIN_REQUIRED contract: the bank item's login credentials or consent have lapsed and the user must log in again through the provider's link flow.
Source
Thrown at packages/desktop-client/src/accounts/syncStatus.ts:23
) {
const status = account.bank_sync_status;
return (
status != null &&
status !== 'ok' &&
status !== 'pending' &&
status !== 'sync-requested'
);
}
export function getFailedSyncError(
account: Pick<AccountEntity, 'bank_sync_status' | 'account_sync_source'>,
): { type: string; code: string } {
switch (account.bank_sync_status) {
case 'reauth-required':
if (account.account_sync_source === 'simpleFin') {
return { type: 'INVALID_ACCESS_TOKEN', code: 'INVALID_ACCESS_TOKEN' };
}
return { type: 'ITEM_ERROR', code: 'ITEM_LOGIN_REQUIRED' };
case 'attention-required':
return {
type: 'ACCOUNT_NEEDS_ATTENTION',
code: 'ACCOUNT_NEEDS_ATTENTION',
};
case 'rate-limit-exceeded':
return { type: 'RATE_LIMIT_EXCEEDED', code: 'RATE_LIMIT_EXCEEDED' };
case 'timed-out':
return { type: 'TIMED_OUT', code: 'TIMED_OUT' };
case 'account-missing':
return { type: 'ACCOUNT_MISSING', code: 'ACCOUNT_MISSING' };
default:
return { type: 'SYNC_ERROR', code: 'SYNC_ERROR' };
}
}
View on GitHub (pinned to d4334cb6e6)
Solutions
- Trigger the Re-link flow for the account and re-authenticate with the bank
- Check the provider requisition status and recreate it if expired
- After successful re-link, sync the account to clear 'reauth-required'
- Set a reminder to re-auth before consent expiry if the bank enforces SCA cycles
Example fix
// before const err = getFailedSyncError(account); // ITEM_LOGIN_REQUIRED // after await openBankLinkFlow(account.id); // user re-enters bank credentials
Defensive patterns
Strategy: validation
Validate before calling
function needsBankRelink(account) {
return account.bank_sync_status === 'reauth-required' &&
account.account_sync_source !== 'simpleFin';
} Type guard
function isSyncErrorDescriptor(v) {
return !!v && typeof v === 'object' && typeof v.type === 'string' && typeof v.code === 'string';
} Prevention
- Check provider item status before each scheduled sync
- Track bank consent/SCA expiry dates and warn users in advance
- Surface a persistent re-link prompt whenever status is 'reauth-required'
When it happens
Trigger: Calling getFailedSyncError on an account with bank_sync_status === 'reauth-required' and account_sync_source other than 'simpleFin'.
Common situations: Bank password changed; user changed online banking credentials; bank requires periodic re-consent (PSD2/SCA with GoCardless); provider marks the item invalid.
Related errors
- Account with ID ${upgradingId} not found.
- Requisition not linked yet
- Provided account id is not linked to given requisition
- res.error_code
- response.reason || response.error_code
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/ad98ea4de773152e.
Report an issue: GitHub.