{"record":{"id":"b5b7cccc59cc43df","repo":"actualbudget/actual","slug":"invalid-widget-idx-type-value-string-widget-t","errorCode":null,"errorMessage":"Invalid widget.${idx}.type value ${String(widget.type)}.","messagePattern":"Invalid widget\\.(.+?)\\.type value (.+?)\\.","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"packages/loot-core/src/server/dashboard/app.ts","lineNumber":96,"sourceCode":"      if (!Number.isInteger(widget.y)) {\n        throw new ValidationError(\n          `Invalid widget.${idx}.y data-type for value ${widget.y}.`,\n        );\n      }\n\n      if (!Number.isInteger(widget.width)) {\n        throw new ValidationError(\n          `Invalid widget.${idx}.width data-type for value ${widget.width}.`,\n        );\n      }\n\n      if (!Number.isInteger(widget.height)) {\n        throw new ValidationError(\n          `Invalid widget.${idx}.height data-type for value ${widget.height}.`,\n        );\n      }\n\n      if (!isWidgetType(widget.type)) {\n        throw new ValidationError(\n          `Invalid widget.${idx}.type value ${String(widget.type)}.`,\n        );\n      }\n\n      if (isExportedCustomReportWidget(widget)) {\n        reportModel.validate(widget.meta);\n      }\n    });\n  },\n};\n\nasync function createDashboardPage({ name }: { name: string }) {\n  const id = uuidv4();\n  await db.insertWithSchema('dashboard_pages', { id, name });\n\n  return id;\n}","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/actualbudget/actual/blob/d4334cb6e6123f4d3bcea1ad6166608884c7e658/packages/loot-core/src/server/dashboard/app.ts#L78-L114","documentation":"During dashboard import, exportModel.validate() checks each widget's `type` against the known widget-type list (net-worth-card, cash-flow-card, custom-report, etc. via isWidgetType). If a widget's type is not one of the supported string literals, a ValidationError is thrown so the import aborts with a clear per-widget message instead of inserting an unrenderable widget.","triggerScenarios":"Calling the dashboard import handler (importDashboard) with a JSON file whose `widgets` array contains an entry whose `type` is misspelled, from a newer/older Actual version, or a non-string value; also any direct call to exportModel.validate with such data.","commonSituations":"Hand-editing an exported dashboard JSON; importing a dashboard exported from a newer Actual version that includes widget types your build doesn't know; typos like 'networth-card' or 'customreport'.","solutions":["Open the JSON file and fix the widget's `type` to one of the supported values listed in isWidgetType (packages/loot-core/src/server/dashboard/app.ts:31).","Re-export the dashboard from a version of Actual compatible with your build, or upgrade Actual so the widget type is supported.","Remove the offending widget entry from the file if it is not needed, keeping x/y/width/height arrays consistent."],"exampleFix":"// before\n{ \"type\": \"networth-card\", \"x\": 0, \"y\": 0, \"width\": 2, \"height\": 1 }\n// after\n{ \"type\": \"net-worth-card\", \"x\": 0, \"y\": 0, \"width\": 2, \"height\": 1 }","handlingStrategy":"validation","validationCode":"const WIDGET_TYPES = ['net-worth-card','cash-flow-card','spending-card','crossover-card','budget-analysis-card','markdown-card','summary-card','calendar-card','formula-card','custom-report','sankey-card','balance-forecast-card','age-of-money-card','monte-carlo-card'];\nfor (const [i, w] of dashboard.widgets.entries()) {\n  if (!WIDGET_TYPES.includes(w.type)) throw new Error(`widget ${i}: unsupported type '${w.type}'`);\n}","typeGuard":"function isWidgetType(type: string): type is DashboardWidgetEntity['type'] {\n  return ['net-worth-card','cash-flow-card','spending-card','crossover-card','budget-analysis-card','markdown-card','summary-card','calendar-card','formula-card','custom-report','sankey-card','balance-forecast-card','age-of-money-card','monte-carlo-card'].includes(type);\n}","tryCatchPattern":"try {\n  await send('dashboard-import', { filePath, dashboardPageId });\n} catch (e) {\n  if (/Invalid widget\\.\\d+\\.type/.test(e.message)) {\n    console.error('Unsupported widget type in file; fix or remove the widget.');\n  }\n}","preventionTips":["Only import dashboard files exported from the same or older Actual version.","Never hand-edit exported widget `type` fields; copy them from a fresh export.","Lint import files against the known widget-type list before importing."],"tags":["validation","dashboard","import"],"backgroundTag":"invalid-enum-value","analyzedSha":"d4334cb6e6123f4d3bcea1ad6166608884c7e658","analyzedAt":"2026-08-29T01:02:11.213Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}