{"record":{"id":"597845704fd6f9e7","repo":"Budibase/budibase","slug":"calculation-field-name-is-missing-a-field-p","errorCode":null,"errorMessage":"Calculation field \"${name}\" is missing a \"field\" property","messagePattern":"Calculation field \"(.+?)\" is missing a \"field\" property","errorType":"validation","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/sdk/workspace/views/index.ts","lineNumber":170,"sourceCode":"  table: Table,\n  view: Omit<ViewV2, \"id\" | \"version\">\n) {\n  const calculationFields = helpers.views.calculationFields(view)\n\n  guardDuplicateCalculationFields(view)\n  guardDuplicateCountDistinctFields(view)\n\n  if (Object.keys(calculationFields).length > 5) {\n    throw new HTTPError(\n      \"Calculation views can only have a maximum of 5 fields\",\n      400\n    )\n  }\n\n  for (const name of Object.keys(calculationFields)) {\n    const schema = calculationFields[name]\n    if (!schema.field) {\n      throw new HTTPError(\n        `Calculation field \"${name}\" is missing a \"field\" property`,\n        400\n      )\n    }\n\n    const targetSchema = table.schema[schema.field]\n    if (!targetSchema) {\n      throw new HTTPError(\n        `Calculation field \"${name}\" references field \"${schema.field}\" which does not exist in the table schema`,\n        400\n      )\n    }\n\n    const isCount = schema.calculationType === CalculationType.COUNT\n    if (\n      !isCount &&\n      !isNumeric(targetSchema.type) &&\n      !isNumericStaticFormula(targetSchema)","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/views/index.ts#L152-L188","documentation":"Every calculation field must declare which column it aggregates via the field property. When a calculation entry lacks field (empty/undefined), the guard rejects it with 400, since the aggregate would have no target column.","triggerScenarios":"A calculation view schema entry like { name: { calculationType: \"sum\" } } with no field key, e.g. from hand-written JSON or a builder state bug.","commonSituations":"Manual API calls omitting field; deserialization dropping empty properties; partially filled form submitted; template copy where field was never set.","solutions":["Add the field property naming an existing table column to every calculation entry","Validate the payload client-side before submitting","Fix the producing code/form that generated the incomplete entry"],"exampleFix":"// before\ncalculations: { total: { calculationType: \"sum\" } }\n// after\ncalculations: { total: { field: \"amount\", calculationType: \"sum\" } }","handlingStrategy":"validation","validationCode":"for (const [name, c] of Object.entries(view.calculations ?? {})) {\n  if (!c.field) throw new Error(`Calculation \"${name}\" missing field`)\n}","typeGuard":"function hasField(c: unknown): c is { field: string; calculationType: CalculationType } {\n  return typeof c === \"object\" && c !== null && typeof (c as any).field === \"string\" && (c as any).field.length > 0\n}","tryCatchPattern":"try { await sdk.views.create(tableId, view) }\ncatch (e) {\n  if (e instanceof HTTPError && e.status === 400 && /missing a \"field\" property/.test(e.message)) {\n    // fix payload and retry\n  } else throw e\n}","preventionTips":["Require the target column when adding a calculation in the UI","Validate calculation entries before submit","Avoid hand-writing view JSON; use typed helpers"],"tags":["http-400","views","validation","calculations"],"backgroundTag":"schema-validation-failed","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}