actualbudget/actual · error · ValidationError

Invalid widget.${idx}.type value ${String(widget.type)}.

Error message

Invalid widget.${idx}.type value ${String(widget.type)}.

What it means

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.

Source

Thrown at packages/loot-core/src/server/dashboard/app.ts:96

      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)) {
        reportModel.validate(widget.meta);
      }
    });
  },
};

async function createDashboardPage({ name }: { name: string }) {
  const id = uuidv4();
  await db.insertWithSchema('dashboard_pages', { id, name });

  return id;
}

View on GitHub (pinned to d4334cb6e6)

Solutions

  1. 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).
  2. Re-export the dashboard from a version of Actual compatible with your build, or upgrade Actual so the widget type is supported.
  3. Remove the offending widget entry from the file if it is not needed, keeping x/y/width/height arrays consistent.

Example fix

// before
{ "type": "networth-card", "x": 0, "y": 0, "width": 2, "height": 1 }
// after
{ "type": "net-worth-card", "x": 0, "y": 0, "width": 2, "height": 1 }
Defensive patterns

Strategy: validation

Validate before calling

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'];
for (const [i, w] of dashboard.widgets.entries()) {
  if (!WIDGET_TYPES.includes(w.type)) throw new Error(`widget ${i}: unsupported type '${w.type}'`);
}

Type guard

function isWidgetType(type: string): type is DashboardWidgetEntity['type'] {
  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);
}

Try / catch

try {
  await send('dashboard-import', { filePath, dashboardPageId });
} catch (e) {
  if (/Invalid widget\.\d+\.type/.test(e.message)) {
    console.error('Unsupported widget type in file; fix or remove the widget.');
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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'.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of actualbudget/actual@d4334cb6e6 (2026-08-29). Data as JSON: /api/errors/b5b7cccc59cc43df. Report an issue: GitHub.