{"record":{"id":"6667ab035dd8dd19","repo":"actualbudget/actual","slug":"field-field-does-not-exist-on-table-table","errorCode":null,"errorMessage":"Field \"${field}\" does not exist on table ${table}: ${JSON.stringify(obj)}","messagePattern":"Field \"(.+?)\" does not exist on table (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/loot-core/src/server/aql/schema-helpers.ts","lineNumber":120,"sourceCode":"  // Rename fields if necessary\n  const fieldRef = field => {\n    if (views[table] && views[table].fields) {\n      return views[table].fields[field] || field;\n    }\n    return field;\n  };\n\n  return Object.fromEntries(\n    Object.keys(obj)\n      .map(field => {\n        // Fields that start with an underscore are ignored\n        if (field[0] === '_') {\n          return null;\n        }\n\n        const fieldDesc = tableSchema[field];\n        if (fieldDesc == null) {\n          throw new Error(\n            `Field \"${field}\" does not exist on table ${table}: ${JSON.stringify(\n              obj,\n            )}`,\n          );\n        }\n\n        if (isRequired(field, fieldDesc) && obj[field] == null) {\n          throw new Error(\n            `\"${field}\" is required for table \"${table}\": ${JSON.stringify(\n              obj,\n            )}`,\n          );\n        }\n\n        // treat undefined as missing\n        if (obj[field] === undefined) {\n          return null;\n        }","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/loot-core/src/server/aql/schema-helpers.ts#L102-L138","documentation":"conform rejects any field in the input object that is not declared in the table's schema (fields starting with '_' are exempt and ignored). This prevents accidentally writing unexpected columns to the database, and the error includes the whole object to aid debugging.","triggerScenarios":"Passing an object to insert/update/query building that contains extra keys — e.g. a raw API response, a joined row, or renamed fields — into convertForInsert/convertForUpdate for a table where those keys are not in the schema.","commonSituations":"Spreading fetched records (with metadata like 'tombstone' variants or computed fields) straight into inserts, schema migrations renaming a column while old call sites still use the old field name, and typos in field names ('amout' vs 'amount').","solutions":["Strip unknown fields before calling: build the object from only the known schema fields.","Prefix internal/metadata keys with '_' so conform ignores them.","Fix the field name typo or update to the renamed schema field.","Check the table schema for the exact accepted field names before constructing the object."],"exampleFix":"// before\nconvertForInsert(schema, schemaConfig, 'transactions', { ...txn, payeeName: 'X' });\n// after\nconst { payeeName, ...valid } = txn;\nconvertForInsert(schema, schemaConfig, 'transactions', valid);","handlingStrategy":"validation","validationCode":"function pickSchemaFields(obj, tableSchema) {\n  return Object.fromEntries(\n    Object.entries(obj).filter(([k]) => k.startsWith('_') || tableSchema[k] != null),\n  );\n}","typeGuard":null,"tryCatchPattern":"try {\n  return convertForUpdate(schema, schemaConfig, table, obj);\n} catch (e) {\n  if (e.message.includes('does not exist on table')) {\n    logger.error('Unknown field passed to update', { obj });\n    // strip unknown fields and retry, or rethrow\n  }\n  throw e;\n}","preventionTips":["Never spread raw API/import records into insert/update objects","Prefix internal metadata keys with '_'","Validate field names against the table schema in tests"],"tags":["schema","field","validation","aql"],"backgroundTag":"unknown-schema-field","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}