actualbudget/actual · error · APIError

Provide a valid type

Error message

Provide a valid type

What it means

The 'api/get-id-by-name' handler resolves a name to an id only for a fixed set of entity types: payees, categories, schedules, accounts. Any other type value throws this APIError before a query is run.

Source

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

      resetNextDate,
    });
  } else {
    return sched.id;
  }
});

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;

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Pass exactly one of: 'payees', 'categories', 'schedules', 'accounts'.
  2. Fix singular/plural mismatches (use 'payees', not 'payee').
  3. Validate/whitelist the type in wrapper code before calling.

Example fix

// before
await q.getIdByName('payee', 'Alice');
// after
await q.getIdByName('payees', 'Alice');
Defensive patterns

Strategy: validation

Validate before calling

const TYPES = ['payees', 'categories', 'schedules', 'accounts'];
if (!TYPES.includes(type)) throw new Error(`type must be one of ${TYPES.join(', ')}`);
const id = await actual.getIdByName(type, name);

Type guard

function isLookupType(t) {
  return ['payees','categories','schedules','accounts'].includes(t);
}

Try / catch

try {
  const id = await actual.getIdByName(type, name);
} catch (e) {
  if (String(e.message) === 'Provide a valid type') {
    console.error('Use plural type names: payees, categories, schedules, accounts');
  } else throw e;
}

Prevention

When it happens

Trigger: Calling getIdByName with type values like 'payee' (singular), 'transactions', 'rules', null, or undefined.

Common situations: Guessing the type string instead of checking the API docs; singular/plural confusion; passing a table name from a different tool's schema.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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