actualbudget/actual · error

Either `filepath` or `buffer` must be given

Error message

Either `filepath` or `buffer` must be given

What it means

`importBudget` requires exactly one input source: a `filepath` on disk or an in-memory `buffer`. If neither is provided (both undefined/null), the function throws this guard error instead of proceeding. It is a straightforward precondition check so callers fail fast with an unambiguous message.

Source

Thrown at packages/loot-core/src/server/budgetfiles/app.ts:499

   * to derive the budget name for some import types.
   */
  filename?: string;
}): Promise<{ error?: string; meta?: unknown; id?: string }> {
  try {
    let contents: Buffer;
    let name: string;
    if (filepath != null) {
      if (!(await fs.exists(filepath))) {
        throw new Error(`File not found at the provided path: ${filepath}`);
      }

      contents = Buffer.from(await fs.readFile(filepath, 'binary'));
      name = filepath;
    } else if (buffer != null) {
      contents = Buffer.from(buffer);
      name = filename || 'budget-import';
    } else {
      throw new Error('Either `filepath` or `buffer` must be given');
    }

    const results = await handleBudgetImport(type, name, contents);
    if (results && results.error) {
      return results;
    }
    // A successful import leaves the imported budget loaded
    return { id: prefs.getPrefs()?.id };
  } catch (err) {
    err.message = 'Error importing budget: ' + err.message;
    captureException(err);
    return { error: 'internal-error' };
  }
}

async function exportBudget() {
  try {
    const exported = await cloudStorage.exportBuffer();

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. Pass either `filepath` (an existing server-side path) or `buffer` (a Uint8Array/Buffer of the file contents) to `importBudget`.
  2. If the data comes from an upload or the client, prefer the `buffer` form: `Buffer.from(await file.arrayBuffer())`.
  3. Validate before calling: reject requests where both fields are missing with your own clear message.
  4. Check for empty-string values — `''` and `null` will both land in this error branch; require a non-empty path string.

Example fix

// before
await importBudget({ type: 'ynab4' }); // neither source given

// after
const contents = await fs.readFile('budget.yfull');
await importBudget({ type: 'ynab4', buffer: contents });
Defensive patterns

Strategy: validation

Validate before calling

function assertImportSource(params) {
  const hasPath = typeof params.filepath === 'string' && params.filepath.length > 0;
  const hasBuffer = params.buffer != null && params.buffer.length > 0;
  if (!hasPath && !hasBuffer) {
    throw new Error('importBudget requires a non-empty `filepath` or `buffer`');
  }
}

Type guard

function hasImportSource(params) {
  return (
    (typeof params.filepath === 'string' && params.filepath.length > 0) ||
    (params.buffer instanceof Uint8Array && params.buffer.length > 0)
  );
}

Try / catch

try {
  await importBudget({ type, filepath, buffer });
} catch (e) {
  if (e.message.includes('`filepath` or `buffer` must be given')) {
    console.error('No import source provided — attach the uploaded file first');
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling `importBudget({ type })` with no source at all; passing both `filepath: undefined` and `buffer: undefined` due to a failed destructuring or an object built conditionally where the key was omitted; passing empty strings or `null` (which fail the `!= null` / truthiness checks used to pick the branch).

Common situations: API consumers reading the source/params from a request body where the file field was not uploaded; a wrapper function forwarding `undefined` because an earlier await failed silently; TypeScript callers relying on optional props and never setting either; switching code from `filepath` to `buffer` (or vice versa) but deleting one key without setting the other.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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