{"record":{"id":"9c15e9f6d327d900","repo":"actualbudget/actual","slug":"error-parsing-budget-yfull-file","errorCode":null,"errorMessage":"Error parsing Budget.yfull file","messagePattern":"Error parsing Budget\\.yfull file","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/loot-core/src/server/importers/ynab4.ts","lineNumber":476,"sourceCode":"    e.startsWith(join(budgetPath, 'devices')),\n  );\n  const deviceGUID = findLatestDevice(zipped, deviceFiles);\n\n  const yfullPath = join(budgetPath, deviceGUID, 'Budget.yfull');\n  let contents;\n  try {\n    contents = Buffer.from(zipped[getFile(entries, yfullPath)]).toString(\n      'utf8',\n    );\n  } catch (e) {\n    logger.log(e);\n    throw new Error('Error reading Budget.yfull file');\n  }\n\n  try {\n    return JSON.parse(contents);\n  } catch {\n    throw new Error('Error parsing Budget.yfull file');\n  }\n}\n","sourceCodeStart":458,"sourceCodeEnd":479,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/loot-core/src/server/importers/ynab4.ts#L458-L479","documentation":"parseFile parses the Budget.yfull contents with JSON.parse and throws this error when the text is not valid JSON. YNAB4 stores the budget as JSON, so a parse failure means the file content is corrupt, empty, or not actually a YNAB4 yfull document.","triggerScenarios":"parseFile(buffer) where the extracted Budget.yfull entry decodes to text that JSON.parse rejects — truncated file, HTML error page saved inside the zip, or an incompatible file format.","commonSituations":"Zip created from a partially synced cloud folder (file placeholder downloaded empty); user hand-edited Budget.yfull and broke the JSON; importing a YNAB5/nYab archive whose yfull is not plain JSON.","solutions":["Validate the extracted file (python3 -m json.tool Budget.yfull) to confirm whether the JSON is malformed.","Restore a clean Budget.yfull from another YNAB4 backup or re-export from YNAB4.","Ensure the cloud-storage placeholder was fully downloaded (file size > 0) before zipping/importing.","If you edited the file, revert your changes or re-validate the JSON syntax."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"function isBudgetYfullJson(text) {\n  try {\n    const j = JSON.parse(text);\n    return j && typeof j === 'object' && 'version' in j;\n  } catch { return false; }\n}","typeGuard":"function isRecord(v) {\n  return typeof v === 'object' && v !== null && !Array.isArray(v);\n}","tryCatchPattern":"try {\n  const budget = parseFile(buffer);\n} catch (e) {\n  if (e.message === 'Error parsing Budget.yfull file') {\n    // extract Budget.yfull, run python3 -m json.tool to locate the corruption\n  } else throw e;\n}","preventionTips":["Extract and JSON-validate Budget.yfull when imports fail repeatedly.","Beware cloud-storage placeholder files — ensure full download before zipping.","Never hand-edit Budget.yfull without validating the JSON afterwards.","Keep multiple YNAB4 backups; verify the newest one imports before deleting older ones."],"tags":["import","ynab4","json","corrupt-file"],"backgroundTag":"invalid-json","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}