{"record":{"id":"6f8653873a553fd9","repo":"actualbudget/actual","slug":"error-importing-budget-result-error","errorCode":null,"errorMessage":"Error importing budget: ${result.error}","messagePattern":"Error importing budget: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/api/methods.ts","lineNumber":78,"sourceCode":" */\nexport async function importBudget(\n  input: string | ArrayBuffer | Uint8Array,\n  {\n    type = 'actual',\n    filename,\n  }: { type?: ImportableBudgetType; filename?: string } = {},\n): Promise<{ id: string }> {\n  const result =\n    typeof input === 'string'\n      ? await send('import-budget', { filepath: input, type })\n      : await send('import-budget', {\n          buffer: toArrayBuffer(input),\n          filename,\n          type,\n        });\n\n  if (result.error) {\n    throw new Error(`Error importing budget: ${result.error}`);\n  }\n  if (!result.id) {\n    throw new Error('Error importing budget: no budget was loaded');\n  }\n  return { id: result.id };\n}\n\n/** Export the currently-loaded budget as a zip buffer. */\nexport async function exportBudget(): Promise<Uint8Array> {\n  const result = await send('export-budget');\n\n  if ('error' in result) {\n    throw new Error(`Error exporting budget: ${result.error}`);\n  }\n  if (!result.data) {\n    throw new Error('Error exporting budget: no data was returned');\n  }\n  return new Uint8Array(result.data);","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/api/methods.ts#L60-L96","documentation":"importBudget sends the 'import-budget' command to the core with the uploaded budget file. The core responds with an error field when the budget file cannot be imported (unparseable zip, wrong format, migration failure, etc.). The API surfaces that server-side message verbatim so the caller knows the import was rejected.","triggerScenarios":"Calling api.importBudget(buffer, filename, type) with a file that is not a valid Actual budget zip (e.g. an exported .zip from an incompatible version, a truncated/corrupted download, or a random file renamed to .zip).","commonSituations":"Automated migration scripts importing a budget exported from another instance; uploading an encrypted or password-protected zip; feeding a CSV/JSON file instead of an Actual budget file; a partially-uploaded file over an unstable network.","solutions":["Open the file locally (File > Open budget) to confirm it is a valid Actual budget before importing programmatically.","Re-export the budget from a matching Actual version and retry.","Check the error detail embedded in the message for a concrete cause (invalid zip, migration error, etc.).","Ensure the file is passed fully as ArrayBuffer/Uint8Array, not as a string or partially-read stream."],"exampleFix":"// before\nawait api.importBudget(csvBuffer, 'budget.csv', 'text/csv');\n// after\nconst res = await fetch(budgetUrl);\nconst buf = new Uint8Array(await res.arrayBuffer());\nif (!budgetUrl.endsWith('.zip')) throw new Error('Not an Actual budget file');\nawait api.importBudget(buf, 'budget.zip', 'application/zip');","handlingStrategy":"validation","validationCode":"function isPlausibleBudgetFile(buf: Uint8Array, name: string): boolean {\n  const isZip = buf.length > 4 && buf[0] === 0x50 && buf[1] === 0x4b && buf[2] === 0x03 && buf[3] === 0x04;\n  return isZip && name.endsWith('.zip') && buf.length > 1024;\n}\nif (!isPlausibleBudgetFile(buffer, filename)) throw new Error('Refusing to import: not a budget zip');","typeGuard":"function isImportFailure(r: { error?: string; id?: string }): r is { error: string } {\n  return typeof r.error === 'string' && r.error.length > 0;\n}","tryCatchPattern":"try {\n  const { id } = await api.importBudget(buffer, 'budget.zip', 'application/zip');\n} catch (e) {\n  if (String(e.message).startsWith('Error importing budget:')) {\n    console.error('Budget import rejected:', e.message);\n    // surface to user / retry with a valid export\n  } else throw e;\n}","preventionTips":["Only import .zip files produced by Actual's export/open.","Verify the zip opens locally before scripted imports.","Transfer files in binary mode; check byte length after download.","Keep @actual-app/api and the server on matching versions."],"tags":["import","budget","file-format","api"],"backgroundTag":"budget-import-failed","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}