actualbudget/actual · error · ValidationError
Invalid widget.${idx}.width data-type for value ${widget.wid
Error message
Invalid widget.${idx}.width data-type for value ${widget.width}. What it means
Each widget's width (grid column span) must be an integer. The dashboard import validator throws this ValidationError when widget.width is a float, string, null, or undefined, since spans must map to whole grid columns.
Source
Thrown at packages/loot-core/src/server/dashboard/app.ts:84
'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(
`Invalid widget.${idx}.height data-type for value ${widget.height}.`,
);
}
if (!isWidgetType(widget.type)) {
throw new ValidationError(
`Invalid widget.${idx}.type value ${String(widget.type)}.`,
);
}
if (isExportedCustomReportWidget(widget)) {View on GitHub (pinned to d4334cb6e6)
Solutions
- Set widget.width = Math.round(widget.width) before import.
- Give every widget an explicit integer width (typically 1–4 grid columns).
- Convert string values with Number() and check Number.isInteger.
- Fix the generator to emit integer spans.
- Re-export from the app to obtain valid widths.
Example fix
// before width: Math.floor(cols / widgets.length) // after (guaranteed integer, >= 1) width: Math.max(1, Math.round(cols / widgets.length))
Defensive patterns
Strategy: validation
Validate before calling
widgets.forEach((w, i) => {
if (!Number.isInteger(w.width)) throw new Error(`Widget #${i}: width must be an integer, got ${w.width}`);
}); Type guard
function hasIntegerWidth(w: { width: unknown }): w is { width: number } {
return Number.isInteger(w.width);
} Try / catch
try {
await send('dashboard-import', { version: 1, widgets });
} catch (e) {
if (e instanceof ValidationError && e.message.includes('.width data-type')) {
console.error('Non-integer width in import; round spans and retry');
} else throw e;
} Prevention
- Use Math.max(1, Math.round(span)) when deriving widths from ratios.
- Validate all geometry fields (x, y, width, height) together.
- Avoid spreadsheet-based JSON editing that produces string numerics.
- Prefer whole grid-column constants (1–4) in generated layouts.
When it happens
Trigger: Importing dashboard JSON where a widget's width is 1.5, "2", null, or absent; exports generated from percentage-based sizing math.
Common situations: Responsive layout generators dividing available width; spreadsheet edits turning numbers into strings; hand-written widget definitions missing width.
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}.x data-type for value ${widget.x}.
- Invalid widget.${idx}.y data-type for value ${widget.y}.
- 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/4ada5277211884a3.
Report an issue: GitHub.