{"record":{"id":"db326dab468291f0","repo":"actualbudget/actual","slug":"name-is-missing-field-string-field","errorCode":null,"errorMessage":"${name} is missing field ${String(field)}","messagePattern":"(.+?) is missing field (.+?)","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"packages/loot-core/src/server/models.ts","lineNumber":32,"sourceCode":"import type {\n  DbAccount,\n  DbAccountGroup,\n  DbCategory,\n  DbCategoryGroup,\n  DbPayee,\n} from './db';\nimport { ValidationError } from './errors';\n\nexport function requiredFields<T extends object, K extends keyof T>(\n  name: string,\n  row: T,\n  fields: K[],\n  update?: boolean,\n) {\n  fields.forEach(field => {\n    if (update) {\n      if (row.hasOwnProperty(field) && row[field] == null) {\n        throw new ValidationError(`${name} is missing field ${String(field)}`);\n      }\n    } else {\n      if (!row.hasOwnProperty(field) || row[field] == null) {\n        throw new ValidationError(`${name} is missing field ${String(field)}`);\n      }\n    }\n  });\n}\n\nexport function toDateRepr(str: string) {\n  if (typeof str !== 'string') {\n    throw new Error('toDateRepr not passed a string: ' + str);\n  }\n\n  return parseInt(str.replace(/-/g, ''));\n}\n\nexport function fromDateRepr(number: number) {","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/loot-core/src/server/models.ts#L14-L50","documentation":"requiredFields validates that a model row contains all required fields before database writes via validate(). For inserts (update=false) every listed field must exist and be non-null; for updates, a present field must not be null. Violations throw a ValidationError naming the model and the missing field, e.g. 'transactions is missing field account'.","triggerScenarios":"Calling model APIs (e.g. transactions-add, account-create, schedule or payee creation via the API/app) with an object that omits a required field or explicitly sets it to null/undefined — such as adding a transaction without account, or creating an account without name/balance fields.","commonSituations":"Scripting the @actual-app/api and forgetting mandatory fields; custom importers building rows incompletely; plugins or automation passing partial update objects where a null slipped in; version changes making a previously optional field required.","solutions":["Read the validation message to see which model and field failed, then include that field with a valid non-null value in your call.","For transaction adds, always pass account (id or name resolvable), date, and amount.","For updates, omit fields you don't intend to change instead of sending null.","If you believe the field should be optional, check the model definition in packages/loot-core/src/server/models.ts to confirm the required list before filing an issue."],"exampleFix":"// before\nawait api.addTransactions('My Account', [{ date: '2026-08-28', amount: -1234 }]);\n// error: transactions is missing field account (id mismatch) — resolve by name to id\n// after\nconst acct = await api.getAccount('My Account');\nawait api.addTransactions(acct.id, [{ date: '2026-08-28', amount: -1234 }]);","handlingStrategy":"try-catch","validationCode":"const REQUIRED = { transactions: ['account','date','amount'] };\nfunction validateRow(model, row) {\n  for (const f of REQUIRED[model] || []) {\n    if (row?.[f] == null) throw new ValidationError(`${model} is missing field ${f}`);\n  }\n}","typeGuard":"function hasRequiredFields(row, fields) {\n  return typeof row === 'object' && row !== null &&\n    fields.every(f => f in row && row[f] != null);\n}","tryCatchPattern":"try {\n  await api.addTransactions(accountId, txs);\n} catch (e) {\n  if (e.name === 'ValidationError' && e.message.includes('is missing field')) {\n    const field = e.message.split('missing field ')[1];\n    // supply the missing field and retry\n  } else throw e;\n}","preventionTips":["Check the model's required field list in packages/loot-core/src/server/models.ts before scripting inserts.","For updates, omit unchanged fields rather than sending null.","Wrap API automation in validation that asserts required fields exist before calls.","Keep integrations updated when upgrading Actual, as required field sets can change."],"tags":["validation","database","api"],"backgroundTag":"missing-required-field","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}