actualbudget/actual · error · APIError

Not found: ${type} with name ${name}

Error message

Not found: ${type} with name ${name}

What it means

After validating the type, 'api/get-id-by-name' queries the entity table filtered by exact name. If no rows come back, it throws this APIError indicating no entity of that type has that name. The filter is exact-name matching, so partial or case-differing names will not match.

Source

Thrown at packages/loot-core/src/server/api.ts:1103

handlers['api/schedule-delete'] = withMutation(async function (id: string) {
  checkFileOpen();
  return handlers['schedule/delete']({ id });
});

handlers['api/get-id-by-name'] = async function ({ type, name }) {
  checkFileOpen();

  const allowedTypes = ['payees', 'categories', 'schedules', 'accounts'];

  if (!allowedTypes.includes(type)) {
    throw APIError('Provide a valid type');
  }

  const { data } = await aqlQuery(q(type).filter({ name }).select('*'));

  if (!data || data.length === 0) {
    throw APIError(`Not found: ${type} with name ${name}`);
  }

  return data[0].id;
};

handlers['api/get-server-version'] = async function () {
  return handlers['get-server-version']();
};

export function installAPI(serverHandlers: ServerHandlers) {
  const merged = Object.assign({}, serverHandlers, handlers);
  handlers = merged as Handlers;
  return merged;
}

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Verify the entity exists with that exact name in the budget (case-sensitive).
  2. Trim whitespace and match capitalization, or look up via a case-insensitive search first.
  3. Create the entity before resolving its id, or handle the not-found case in caller code.

Example fix

// before
const id = await q.getIdByName('accounts', ' checking ');
// after
const id = await q.getIdByName('accounts', 'Checking');
Defensive patterns

Strategy: try-catch

Validate before calling

const payees = await actual.getPayees();
const match = payees.find(p => p.name === name);
if (!match) throw new Error(`No payee named '${name}' in this budget`);

Try / catch

try {
  const id = await actual.getIdByName('payees', name);
} catch (e) {
  if (String(e.message).startsWith('Not found:')) {
    // create the entity or pick a different name
  } else throw e;
}

Prevention

When it happens

Trigger: Calling getIdByName with a name that doesn't exactly match an existing entity — misspellings, trailing whitespace, different capitalization, or the entity was deleted/renamed.

Common situations: Hardcoded names that drifted from the actual budget data; creating the entity in a different budget file than the one queried; case sensitivity surprises ('alice' vs 'Alice').

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/b39755eea2ef3156. Report an issue: GitHub.