octobercms/october · error · SystemException

backend::lang.field.invalid_type

backend::lang.field.invalid_type

Error message

Invalid field type used :type.

What it means

Dash::makeDashReport builds a DashReport from a name and config array; the type key drives displayAs(). Winter/October requires type to be a string (or absent). If the config carries a non-string type - array, integer, boolean - a SystemException with the backend::lang.field.invalid_type message is thrown before the widget is created. It is a config-format guard, not a runtime data error.

Source

Thrown at modules/dashboard/widgets/Dash.php:453

                $name = $widget['reportName'] ?? 'custom_report_' . str_random();
                $this->allReports[$name] = $this->makeDashReport((string) $name, $widget);
            }
        }
    }

    /**
     * makeDashReport creates a dash report object from name and configuration
     */
    protected function makeDashReport(string $name, $config = []): DashReport
    {
        $report = new DashReport([
            'reportName' => $name,
            'label' => $config['label'] ?? null,
        ]);

        $reportType = $config['type'] ?? null;
        if (!is_string($reportType) && $reportType !== null) {
            throw new SystemException(Lang::get(
                'backend::lang.field.invalid_type',
                ['type' => gettype($reportType)]
            ));
        }

        if ($config) {
            $report->useConfig($config);
        }

        if ($reportType) {
            $report->displayAs($reportType);
        }

        return $report;
    }

    /**
     * loadInitialState for the dashboards

View on GitHub (pinned to b608633a7e)

Solutions

  1. Fix the definition so type is a single string, e.g. type: sum instead of type: [sum].
  2. Cast before building: pass ['type' => (string) $type] when the value comes from storage or user input.
  3. Remove the type key entirely if the default report type is intended.
  4. Validate the definition payload (YAML lint / JSON schema) before it reaches the dashboard widget.

Example fix

# before (dashboard definition)
reports:
  sales:
    type: [sum]
# after
reports:
  sales:
    type: sum
Defensive patterns

Strategy: type-guard

Validate before calling

$type = $config['type'] ?? null;
if ($type !== null && !is_string($type)) {
    throw new \InvalidArgumentException('report type must be a string');
}

Type guard

/** True when the report config's type key is safe for Dash. */
function isValidReportType(array $config): bool
{
    $t = $config['type'] ?? null;
    return $t === null || is_string($t);
}

Try / catch

try {
    $dash->makeReport($name, $config);
} catch (\SystemException $e) {
    // config came from user/storage: report which key is malformed
    \Log::warning('Bad report config for '.$name.': '.json_encode($config));
}

Prevention

When it happens

Trigger: A dashboard definition (YAML or saved JSON definition) contains type: [sum, avg] or type: 10 or type: true for a report; programmatic calls like $dash->makeReport('sales', ['type' => ['sum']]); POSTed widget configuration where type arrives as a nested array from a malformed form payload.

Common situations: Hand-edited dashboard YAML using YAML list syntax for a scalar; a migration or seed script assigning type from an uncast database column; type coming from user input that was never cast to string; version upgrades where a widget type key changed shape.

Related errors


AI-assisted analysis of octobercms/october@b608633a7e (2026-08-21). Data as JSON: /api/errors/f48f794ce4c6a8cf. Report an issue: GitHub.