{"record":{"id":"f5ccc389332da22f","repo":"actualbudget/actual","slug":"can-t-convert-to-integer","errorCode":null,"errorMessage":"Can't convert to integer: ","messagePattern":"Can't convert to integer: ","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/loot-core/src/server/aql/schema-helpers.ts","lineNumber":49,"sourceCode":"      }\n\n      return toDateRepr(value);\n    case 'date-month':\n      return toDateRepr(value.slice(0, 7));\n    case 'date-year':\n      return toDateRepr(value.slice(0, 4));\n    case 'boolean':\n      return value ? 1 : 0;\n    case 'id':\n      if (typeof value !== 'string' && value !== null) {\n        throw new Error('Invalid id, must be string: ' + value);\n      }\n      return value;\n    case 'integer':\n      if (typeof value === 'number' && Number.isInteger(value)) {\n        return value;\n      } else {\n        throw new Error(\"Can't convert to integer: \" + JSON.stringify(value));\n      }\n    case 'json':\n      return JSON.stringify(value);\n    default:\n  }\n  return value;\n}\n\nexport function convertOutputType(value, type) {\n  if (value === null) {\n    if (type === 'boolean') {\n      return false;\n    }\n    return null;\n  }\n\n  switch (type) {\n    case 'date':","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/loot-core/src/server/aql/schema-helpers.ts#L31-L67","documentation":"`integer`-typed fields only accept whole JavaScript numbers. Any other value (float, string, boolean, object) is rejected with 'Can't convert to integer' — the helper casts but does not coerce numeric strings, per the TODO in the source noting these conversions are really casts.","triggerScenarios":"Passing a string like '5' from form/URL input, a float like 12.5, null-like sentinel values, or a parsed amount ('-10.99') into an `integer` field in an aql query.","commonSituations":"Money amounts from user input arriving as decimal strings/floats and being stored in integer fields that expect cents, sort orders or flags read from JSON as strings, and CSV imports where all cells are strings.","solutions":["Coerce explicitly before querying: `Number(value)` and validate with `Number.isInteger` yourself.","Round/convert money to integer cents first (e.g. `Math.round(amount * 100)`).","Fix the upstream producer so the value is a number, not a numeric string.","If the field should allow fractions or strings, it is typed wrong in the schema — reconsider the column type."],"exampleFix":"// before\nq('transactions').insert({ amount: String(cents) }); // '500'\n// after\nconst amount = Number(cents);\nif (!Number.isInteger(amount)) throw new Error('bad amount');\nq('transactions').insert({ amount });","handlingStrategy":"validation","validationCode":"const asInt = (v) => {\n  const n = Number(v);\n  if (!Number.isInteger(n)) throw new Error(`expected integer, got ${JSON.stringify(v)}`);\n  return n;\n};","typeGuard":"const isInteger = (v) => typeof v === 'number' && Number.isInteger(v);","tryCatchPattern":"try {\n  return await runQuery(q.filter({ amount }));\n} catch (e) {\n  if (e.message.startsWith(\"Can't convert to integer:\")) {\n    logger.error('Non-integer value for integer field', { amount });\n    return null;\n  }\n  throw e;\n}","preventionTips":["Convert money to integer cents with Math.round(amount * 100) before storing","Parse numeric form/URL input with Number() before querying","Keep numeric fields as numbers end-to-end; never stringify amounts"],"tags":["integer","types","validation","aql"],"backgroundTag":"integer-type-cast-failed","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}