diff --git a/packages/loot-core/src/server/api.ts b/packages/loot-core/src/server/api.ts
index c2aab6d12cce63ec0903f00436b5b5104a49c79f..c36da3398918b37c82e2770e763bc19045e3960b 100644
--- a/packages/loot-core/src/server/api.ts
+++ b/packages/loot-core/src/server/api.ts
@@ -101,6 +101,12 @@ async function validateExpenseCategory(debug, id) {
   }
 }
 
+function checkFileOpen() {
+  if (!(prefs.getPrefs() || {}).id) {
+    throw APIError('No budget file is open');
+  }
+}
+
 let batchPromise = null;
 
 handlers['api/batch-budget-start'] = async function () {
@@ -225,6 +231,8 @@ handlers['api/start-import'] = async function ({ budgetName }) {
 };
 
 handlers['api/finish-import'] = async function () {
+  checkFileOpen();
+
   sheet.get().markCacheDirty();
 
   // We always need to fully reload the app. Importing doesn't touch
@@ -245,6 +253,8 @@ handlers['api/finish-import'] = async function () {
 
 handlers['api/abort-import'] = async function () {
   if (IMPORT_MODE) {
+    checkFileOpen();
+
     let { id } = prefs.getPrefs();
 
     await handlers['close-budget']();
@@ -256,15 +266,18 @@ handlers['api/abort-import'] = async function () {
 };
 
 handlers['api/query'] = async function ({ query }) {
+  checkFileOpen();
   return aqlQuery(query);
 };
 
 handlers['api/budget-months'] = async function () {
+  checkFileOpen();
   let { start, end } = await handlers['get-budget-bounds']();
   return monthUtils.range(start, end);
 };
 
 handlers['api/budget-month'] = async function ({ month }) {
+  checkFileOpen();
   await validateMonth(month);
 
   let groups = await db.getCategoriesGrouped();
@@ -326,6 +339,7 @@ handlers['api/budget-set-amount'] = withMutation(async function ({
   categoryId,
   amount,
 }) {
+  checkFileOpen();
   return handlers['budget/budget-amount']({
     month,
     category: categoryId,
@@ -338,6 +352,7 @@ handlers['api/budget-set-carryover'] = withMutation(async function ({
   categoryId,
   flag,
 }) {
+  checkFileOpen();
   await validateMonth(month);
   await validateExpenseCategory('budget-set-carryover', categoryId);
   return handlers['budget/set-carryover']({
@@ -352,6 +367,7 @@ handlers['api/transactions-export'] = async function ({
   categoryGroups,
   payees,
 }) {
+  checkFileOpen();
   return handlers['transactions-export']({
     transactions,
     categoryGroups,
@@ -363,6 +379,7 @@ handlers['api/transactions-import'] = withMutation(async function ({
   accountId,
   transactions,
 }) {
+  checkFileOpen();
   return handlers['transactions-import']({ accountId, transactions });
 });
 
@@ -370,6 +387,7 @@ handlers['api/transactions-add'] = withMutation(async function ({
   accountId,
   transactions,
 }) {
+  checkFileOpen();
   await addTransactions(accountId, transactions, { runTransfers: false });
   return 'ok';
 });
@@ -379,6 +397,7 @@ handlers['api/transactions-get'] = async function ({
   startDate,
   endDate,
 }) {
+  checkFileOpen();
   let { data } = await aqlQuery(
     q('transactions')
       .filter({
@@ -402,6 +421,7 @@ handlers['api/transaction-update'] = withMutation(async function ({
   id,
   fields,
 }) {
+  checkFileOpen();
   let { data } = await aqlQuery(
     q('transactions').filter({ id }).select('*').options({ splits: 'grouped' }),
   );
@@ -416,6 +436,7 @@ handlers['api/transaction-update'] = withMutation(async function ({
 });
 
 handlers['api/transaction-delete'] = withMutation(async function ({ id }) {
+  checkFileOpen();
   let { data } = await aqlQuery(
     q('transactions').filter({ id }).select('*').options({ splits: 'grouped' }),
   );
@@ -430,6 +451,7 @@ handlers['api/transaction-delete'] = withMutation(async function ({ id }) {
 });
 
 handlers['api/accounts-get'] = async function () {
+  checkFileOpen();
   let accounts = await db.getAccounts();
   return accounts.map(account => accountModel.toExternal(account));
 };
@@ -438,6 +460,7 @@ handlers['api/account-create'] = withMutation(async function ({
   account,
   initialBalance = null,
 }) {
+  checkFileOpen();
   return handlers['account-create']({
     name: account.name,
     type: account.type,
@@ -450,6 +473,7 @@ handlers['api/account-create'] = withMutation(async function ({
 });
 
 handlers['api/account-update'] = withMutation(async function ({ id, fields }) {
+  checkFileOpen();
   return db.updateAccount({ id, ...accountModel.fromExternal(fields) });
 });
 
@@ -458,6 +482,7 @@ handlers['api/account-close'] = withMutation(async function ({
   transferAccountId,
   transferCategoryId,
 }) {
+  checkFileOpen();
   return handlers['account-close']({
     id,
     transferAccountId,
@@ -466,16 +491,19 @@ handlers['api/account-close'] = withMutation(async function ({
 });
 
 handlers['api/account-reopen'] = withMutation(async function ({ id }) {
+  checkFileOpen();
   return handlers['account-reopen']({ id });
 });
 
 handlers['api/account-delete'] = withMutation(async function ({ id }) {
+  checkFileOpen();
   return handlers['account-close']({ id, forced: true });
 });
 
 handlers['api/categories-get'] = async function ({
   grouped,
 }: { grouped? } = {}) {
+  checkFileOpen();
   let result = await handlers['get-categories']();
   return grouped
     ? result.grouped.map(categoryGroupModel.toExternal)
@@ -485,6 +513,7 @@ handlers['api/categories-get'] = async function ({
 handlers['api/category-group-create'] = withMutation(async function ({
   group,
 }) {
+  checkFileOpen();
   return handlers['category-group-create']({ name: group.name });
 });
 
@@ -492,6 +521,7 @@ handlers['api/category-group-update'] = withMutation(async function ({
   id,
   fields,
 }) {
+  checkFileOpen();
   return handlers['category-group-update']({
     id,
     ...categoryGroupModel.fromExternal(fields),
@@ -502,6 +532,7 @@ handlers['api/category-group-delete'] = withMutation(async function ({
   id,
   transferCategoryId,
 }) {
+  checkFileOpen();
   return handlers['category-group-delete']({
     id,
     transferId: transferCategoryId,
@@ -509,6 +540,7 @@ handlers['api/category-group-delete'] = withMutation(async function ({
 });
 
 handlers['api/category-create'] = withMutation(async function ({ category }) {
+  checkFileOpen();
   return handlers['category-create']({
     name: category.name,
     groupId: category.group_id,
@@ -517,6 +549,7 @@ handlers['api/category-create'] = withMutation(async function ({ category }) {
 });
 
 handlers['api/category-update'] = withMutation(async function ({ id, fields }) {
+  checkFileOpen();
   return handlers['category-update']({
     id,
     ...categoryModel.fromExternal(fields),
@@ -527,6 +560,7 @@ handlers['api/category-delete'] = withMutation(async function ({
   id,
   transferCategoryId,
 }) {
+  checkFileOpen();
   return handlers['category-delete']({
     id,
     transferId: transferCategoryId,
@@ -534,21 +568,25 @@ handlers['api/category-delete'] = withMutation(async function ({
 });
 
 handlers['api/payees-get'] = async function () {
+  checkFileOpen();
   let payees = await handlers['payees-get']();
   return payees.map(payeeModel.toExternal);
 };
 
 handlers['api/payee-create'] = withMutation(async function ({ payee }) {
+  checkFileOpen();
   return handlers['payee-create']({ name: payee.name });
 });
 
 handlers['api/payee-update'] = withMutation(async function ({ id, fields }) {
+  checkFileOpen();
   return handlers['payees-batch-change']({
     updated: [{ id, ...payeeModel.fromExternal(fields) }],
   });
 });
 
 handlers['api/payee-delete'] = withMutation(async function ({ id }) {
+  checkFileOpen();
   return handlers['payees-batch-change']({ deleted: [{ id }] });
 });
 
diff --git a/upcoming-release-notes/1073.md b/upcoming-release-notes/1073.md
new file mode 100644
index 0000000000000000000000000000000000000000..6cc62e817432ebc816a410ad37f8ca75139a0083
--- /dev/null
+++ b/upcoming-release-notes/1073.md
@@ -0,0 +1,6 @@
+---
+category: Maintenance
+authors: [j-f1]
+---
+
+Add a clear error to the API when no budget is open, but you attempted to perform an action that requires a budget to be open.