actualbudget/actual · error · ValidationError
Invalid widget.${idx}.x data-type for value ${widget.x}.
Error message
Invalid widget.${idx}.x data-type for value ${widget.x}. What it means
Each widget's x (grid column position) must be an integer. The dashboard import validator throws this ValidationError when widget.x is a float, string, null, or undefined, because grid coordinates must be whole numbers for the layout engine.
Source
Thrown at packages/loot-core/src/server/dashboard/app.ts:73
if (!Array.isArray(dashboard.widgets)) {
throw new ValidationError(
'Invalid dashboard.widgets data type: it must be an array of widgets.',
);
}
dashboard.widgets.forEach((widget, idx) => {
requiredFields(`Dashboard widget #${idx}`, widget, [
'type',
'x',
'y',
'width',
'height',
...(isExportedCustomReportWidget(widget) ? ['meta' as const] : []),
]);
if (!Number.isInteger(widget.x)) {
throw new ValidationError(
`Invalid widget.${idx}.x data-type for value ${widget.x}.`,
);
}
if (!Number.isInteger(widget.y)) {
throw new ValidationError(
`Invalid widget.${idx}.y data-type for value ${widget.y}.`,
);
}
if (!Number.isInteger(widget.width)) {
throw new ValidationError(
`Invalid widget.${idx}.width data-type for value ${widget.width}.`,
);
}
if (!Number.isInteger(widget.height)) {
throw new ValidationError(View on GitHub (pinned to d4334cb6e6)
Solutions
- Round or floor the x value: widget.x = Math.round(widget.x).
- Ensure every widget object includes a numeric integer x before import.
- Convert string numbers: widget.x = Number(widget.x) then check Number.isInteger.
- Fix the generating script so grid positions come from Math.floor of computed values.
- Re-export from the app to get properly typed coordinates.
Example fix
// before
widgets.push({ type: 'net', x: pos * 1.5, y: 0, width: 1, height: 1 });
// after
widgets.push({ type: 'net', x: Math.round(pos * 1.5), y: 0, width: 1, height: 1 }); Defensive patterns
Strategy: validation
Validate before calling
widgets.forEach((w, i) => {
if (!Number.isInteger(w.x)) throw new Error(`Widget #${i}: x must be an integer, got ${w.x}`);
}); Type guard
function hasIntegerCoord(w: { x: unknown }): w is { x: number } {
return Number.isInteger(w.x);
} Try / catch
try {
await send('dashboard-import', { version: 1, widgets });
} catch (e) {
if (e instanceof ValidationError && e.message.includes('.x data-type')) {
console.error('Non-integer x coordinate in import; round coordinates and retry');
} else throw e;
} Prevention
- Always use Math.round/Math.floor for computed grid positions.
- Validate the full export object before import.
- Avoid JSON round-trips through tools that stringify numbers.
- Write widget coordinates with integer counters, not division results.
When it happens
Trigger: Importing dashboard JSON where a widget's x is e.g. 1.5, "0", null, or the field is absent; hand-editing or programmatically generating the export with non-integer coordinates; parsing coordinates from float math elsewhere.
Common situations: Layouts computed from percentage math producing fractional x values; JSON round-trips through tools that stringify numbers; hand-crafted widget definitions missing x entirely.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Invalid widget.${idx}.y data-type for value ${widget.y}.
- Invalid widget.${idx}.width data-type for value ${widget.wid
- Invalid widget.${idx}.height data-type for value ${widget.he
- Invalid dashboard.widgets data type: it must be an array of
- Invalid widget.${idx}.type value ${String(widget.type)}.
AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29).
Data as JSON: /api/errors/c7de6f67b055188a.
Report an issue: GitHub.