actualbudget/actual · error
Can't convert to integer:
Error message
Can't convert to integer:
What it means
`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.
Source
Thrown at packages/loot-core/src/server/aql/schema-helpers.ts:49
}
return toDateRepr(value);
case 'date-month':
return toDateRepr(value.slice(0, 7));
case 'date-year':
return toDateRepr(value.slice(0, 4));
case 'boolean':
return value ? 1 : 0;
case 'id':
if (typeof value !== 'string' && value !== null) {
throw new Error('Invalid id, must be string: ' + value);
}
return value;
case 'integer':
if (typeof value === 'number' && Number.isInteger(value)) {
return value;
} else {
throw new Error("Can't convert to integer: " + JSON.stringify(value));
}
case 'json':
return JSON.stringify(value);
default:
}
return value;
}
export function convertOutputType(value, type) {
if (value === null) {
if (type === 'boolean') {
return false;
}
return null;
}
switch (type) {
case 'date':View on GitHub (pinned to d4334cb6e6)
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.
Example fix
// before
q('transactions').insert({ amount: String(cents) }); // '500'
// after
const amount = Number(cents);
if (!Number.isInteger(amount)) throw new Error('bad amount');
q('transactions').insert({ amount }); Defensive patterns
Strategy: validation
Validate before calling
const asInt = (v) => {
const n = Number(v);
if (!Number.isInteger(n)) throw new Error(`expected integer, got ${JSON.stringify(v)}`);
return n;
}; Type guard
const isInteger = (v) => typeof v === 'number' && Number.isInteger(v);
Try / catch
try {
return await runQuery(q.filter({ amount }));
} catch (e) {
if (e.message.startsWith("Can't convert to integer:")) {
logger.error('Non-integer value for integer field', { amount });
return null;
}
throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Invalid id, must be string:
- Invalid config file: key "${key}" must be a boolean, got ${t
- Invalid field name, must be a string
- Parameter "${param.paramName}" can't convert to ${type} (alr
- Query value cannot be undefined
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/f5ccc389332da22f.
Report an issue: GitHub.