grafana/grafana · error · Error
Elements is not an object or is null
Error message
Elements is not an object or is null
What it means
Required-field check: elements must be a non-null object. In V2, elements is a map keyed by element id (panels, rows, etc.), not an array. Thrown when getElements returned undefined/null or the transformed dashboard lacks the elements key.
Source
Thrown at public/app/features/dashboard-scene/serialization/transformSceneToSaveModelSchemaV2.ts:854
// Function to know if the dashboard transformed is a valid DashboardV2Spec
export function validateDashboardSchemaV2(dash: unknown): dash is DashboardV2Spec {
if (typeof dash !== 'object' || dash === null || Array.isArray(dash)) {
throw new Error('Dashboard is not an object or is null');
}
// Required properties
if (!('title' in dash) || typeof dash.title !== 'string') {
throw new Error('Title is not a string');
}
if (!('timeSettings' in dash) || typeof dash.timeSettings !== 'object' || dash.timeSettings === null) {
throw new Error('TimeSettings is not an object or is null');
}
if (!('variables' in dash) || !Array.isArray(dash.variables)) {
throw new Error('Variables is not an array');
}
if (!('elements' in dash) || typeof dash.elements !== 'object' || dash.elements === null) {
throw new Error('Elements is not an object or is null');
}
if (!('annotations' in dash) || !Array.isArray(dash.annotations)) {
throw new Error('Annotations is not an array');
}
if (!('layout' in dash) || typeof dash.layout !== 'object' || dash.layout === null) {
throw new Error('Layout is not an object or is null');
}
// Optional properties - only validate if present
if ('description' in dash && dash.description !== undefined && typeof dash.description !== 'string') {
throw new Error('Description is not a string');
}
if ('cursorSync' in dash && dash.cursorSync !== undefined) {
const validCursorSyncValues = ((): string[] => {
const typeValues: DashboardCursorSync[] = ['Off', 'Crosshair', 'Tooltip'];
return typeValues;
})();
View on GitHub (pinned to ae3104e369)
Solutions
- Ensure getElements always returns an object (default to {} for empty dashboards).
- Type the return as Record<string, ElementSpec> so a regression to array is a compile error.
- Unit-test the empty-dashboard transform path.
- Check upstream element-id generation if elements went missing.
Example fix
// before
if (!('elements' in dash) || typeof dash.elements !== 'object' || dash.elements === null) {
throw new Error('Elements is not an object or is null');
}
// after — default in the producer
elements: getElements(scene, dsReferencesMapping, isSnapshot) ?? {}, Defensive patterns
Strategy: type-guard
Validate before calling
const els = getElements(scene, dsRefs, isSnapshot);
if (typeof els !== 'object' || els === null) throw new Error('getElements must return an object'); Type guard
function isElementsObject(dash: unknown): dash is { elements: Record<string, unknown> } {
return typeof dash === 'object' && dash !== null && 'elements' in dash && typeof (dash as any).elements === 'object' && !Array.isArray((dash as any).elements) && (dash as any).elements !== null;
} Try / catch
try { await transformSceneToSaveModelSchemaV2(scene); }
catch (e) {
if (e.message === 'Elements is not an object or is null') reportBug('getElements returned non-object');
else throw e;
} Prevention
- Type getElements' return as Record<string, ElementSpec>.
- Default to {} for empty dashboards.
- Add a unit test for the empty-dashboard path.
When it happens
Trigger: getElements(scene, dsReferencesMapping, isSnapshot) returned undefined; or the scene had no panels and the transformer did not emit an empty object. Also when a future refactor returns an array by mistake.
Common situations: Empty dashboard with no panels where the transformer skipped emitting elements; refactor of getElements that changed its return type; element id collision causing a throw upstream that was caught and returned undefined.
Related errors
- Title is not a string
- TimeSettings is not an object or is null
- Variables is not an array
- Annotations is not an array
- Layout is not an object or is null
AI-assisted analysis of grafana/grafana@ae3104e369 (2026-08-12).
Data as JSON: /api/errors/91fbbd5fabaef69b.
Report an issue: GitHub.