actualbudget/actual · error

Account with ID not found.

Error message

Account with ID ${this.props.accountId} not found.

What it means

AccountInternal's renameAccountName handler looks up the account in the `accounts` prop by `accountId` and throws when no match exists. The component assumes its accounts list is always in sync with the accountId prop; when the list is stale/empty or the id is invalid, the rename cannot proceed and it fails fast.

Solutions

  1. Ensure the accounts list is loaded before rendering the editable name field (gate on accounts.length / loading state).
  2. Look the account up from the server store by id (e.g. via the entity/query layer) instead of only the `accounts` prop, so closed/filtered accounts still resolve.
  3. Return a validation error ('Account not found') to the UI instead of throwing, and clear the stale id by redirecting to the accounts page.

Example fix

// before
const account = this.props.accounts.find(a => a.id === this.props.accountId);
if (!account) throw new Error(`Account with ID ${this.props.accountId} not found.`);

// after
const account = this.props.accounts.find(a => a.id === this.props.accountId);
if (!account) {
  this.setState({ nameError: 'Account not found' });
  return;
}
Defensive patterns

Strategy: validation

Validate before calling

const account = accounts.find(a => a.id === accountId);
if (!account) {
  // account missing/stale — abort rename instead of throwing
  return;
}

Type guard

function isKnownAccount(accounts: AccountEntity[], accountId: string): boolean {
  return accounts.some(a => a.id === accountId);
}

Try / catch

try {
  await renameAccount(accountId, newName);
} catch (e) {
  if (String(e.message).includes('not found')) {
    setError('This account no longer exists.');
  } else throw e;
}

Prevention

When it happens

Trigger: Renaming an account (submitting the rename form) while the `accounts` prop no longer contains the account: the account was deleted in another view/tab, the list hasn't loaded yet, or accountId points to a closed/off-balance account filtered out of `accounts`.

Common situations: Deleting an account from a second browser tab then renaming it in the first; race where the account list query is still loading; navigating to a stale deep-link /accounts/<deleted-id> and editing the name.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29). Data as JSON: /api/errors/dd191691392b8d96. Report an issue: GitHub.

Appendix: source

Thrown at packages/desktop-client/src/components/accounts/Account.tsx:801

  onAddTransaction = () => {
    this.setState({ isAdding: true });
  };

  onSaveName = (name: string) => {
    const accountNameError = validateAccountName(
      name,
      this.props.accountId ?? '',
      this.props.accounts,
    );
    if (accountNameError) {
      this.setState({ nameError: accountNameError });
    } else {
      const account = this.props.accounts.find(
        account => account.id === this.props.accountId,
      );
      if (!account) {
        throw new Error(`Account with ID ${this.props.accountId} not found.`);
      }
      this.props.onUpdateAccount({ ...account, name });
      this.setState({ nameError: '' });
    }
  };

  onToggleExtraBalances = () => {
    this.props.setShowExtraBalances(!this.props.showExtraBalances);
  };

  onMenuSelect = async (
    item:
      | 'link'
      | 'unlink'
      | 'close'
      | 'reopen'
      | 'export'
      | 'remove-sorting'

View on GitHub (pinned to d4334cb6e6)