actualbudget/actual · error

Could not find account for transaction when importing

Error message

Could not find account for transaction when importing

What it means

During YNAB4 (importFromYNAB4) import, isOffBudget(acctId) looks up the account in the in-memory accounts list built from the parsed YNAB budget. If the account id referenced by a transaction is not present in that list, it throws this error. This indicates the YNAB4 export data is internally inconsistent — a transaction references an account that was never registered in the accounts array.

Source

Thrown at packages/loot-core/src/server/importers/ynab4.ts:158

  const accounts = await send('api/accounts-get');
  const payees = await send('api/payees-get');

  function getCategory(id: string) {
    if (id == null || id === 'Category/__Split__') {
      return null;
    } else if (
      id === 'Category/__ImmediateIncome__' ||
      id === 'Category/__DeferredIncome__'
    ) {
      return incomeCategoryId;
    }
    return entityIdMap.get(id);
  }

  function isOffBudget(acctId: string) {
    const acct = accounts.find(acct => acct.id === acctId);
    if (!acct) {
      throw new Error('Could not find account for transaction when importing');
    }
    return acct.offbudget;
  }

  // Go ahead and generate ids for all of the transactions so we can
  // reliably resolve transfers
  for (const transaction of data.transactions) {
    entityIdMap.set(transaction.entityId, uuidv4());

    if (transaction.subTransactions) {
      for (const subTransaction of transaction.subTransactions) {
        entityIdMap.set(subTransaction.entityId, uuidv4());
      }
    }
  }

  const transactionsGrouped = groupBy(data.transactions, 'accountId');

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Re-export/re-copy the complete YNAB4 budget folder and retry the import, ensuring all data files come from the same budget.
  2. Inspect the YNAB data for transactions whose accountId has no matching account and delete or fix them before import.
  3. Catch the error to identify the offending accountId and patch the source data (add the missing account or remap the id) before re-importing.
  4. If ids were remapped by a script, ensure the same entityIdMap is used for both accounts and transactions.

Example fix

// before
const offbudget = isOffBudget(t.accountId); // throws if account missing
// after
const account = accounts.find(a => a.id === t.accountId);
if (!account) {
  console.warn(`Skipping transaction ${t.id}: unknown account ${t.accountId}`);
  continue;
}
const offbudget = account.offbudget;
Defensive patterns

Strategy: validation

Validate before calling

const account = accounts.find(a => a.id === txn.accountId);
if (!account) {
  throw new Error(`YNAB4 data inconsistent: transaction ${txn.id} references unknown account ${txn.accountId}`);
}

Type guard

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

Try / catch

try {
  await importBudget(ynab4Dir);
} catch (e) {
  if (e.message.includes('Could not find account for transaction')) {
    // inspect the YNAB4 export for orphaned transactions, fix, and re-import
  } else throw e;
}

Prevention

When it happens

Trigger: Importing a YNAB4 .yfull/budget whose transaction references an accountId absent from the accounts in the parsed data; calling isOffBudget (via newTransaction) with a corrupted or truncated accountId; the accounts list was built from accounts.yfull while transactions come from a different/incompatible dataset.

Common situations: Corrupted or partially-copied YNAB4 budget directories (missing or mismatched Account.yfull vs Transaction files); hand-edited YNAB data; importing a budget from a different YNAB version where id formats differ.

Related errors


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