BabylonJS/Babylon.js · error

Attempted to get position on empty layout

Error message

Attempted to get position on empty layout

What it means

getPosInLayout navigates a shared-UI layout tree (Layout -> columns -> rows). If the layout object has no columns array (never initialized or reset), the function cannot resolve any position and throws. It is a defensive guard in the layout management utilities.

Source

Thrown at packages/dev/sharedUiComponents/src/components/layout/utils.ts:13

import { type Layout, type LayoutColumn, type LayoutTabsRow } from "./types";

/**
 * Given a column and row number in the layout, return the corresponding column/row
 * @param layout
 * @param column
 * @param row
 * @returns
 */
// eslint-disable-next-line @typescript-eslint/naming-convention
export const getPosInLayout = (layout: Layout, column: number, row?: number): LayoutColumn | LayoutTabsRow => {
    if (!layout.columns) {
        throw new Error("Attempted to get position on empty layout");
    }
    const columnLayout = layout.columns[column];
    if (!columnLayout) {
        throw new Error("Attempted to get an invalid layout column");
    }
    if (row === undefined) {
        return columnLayout;
    }
    return columnLayout.rows[row];
};

/**
 * Remove a row in position row, column from the layout, and redistribute heights of remaining rows
 * @param layout
 * @param column
 * @param row
 */
// eslint-disable-next-line @typescript-eslint/naming-convention

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Initialize layout.columns (e.g. layout.columns = [ ... ]) before calling getPosInLayout
  2. Guard the call: check layout?.columns?.length before invoking
  3. Load a valid default layout when stored/parsed layout data lacks columns (validate on JSON.parse)
  4. Wrap the call in try/catch and fall back to a default column

Example fix

// before
const col = getPosInLayout(loadedLayout, 0); // loadedLayout.columns is undefined -> throws
// after
const col = loadedLayout.columns ? getPosInLayout(loadedLayout, 0) : defaultLayout.columns[0];
Defensive patterns

Strategy: validation

Validate before calling

function hasColumns(layout: Layout): layout is Layout & { columns: LayoutColumn[] } {
    return Array.isArray(layout.columns) && layout.columns.length > 0;
}
// usage
if (hasColumns(layout)) { const col = getPosInLayout(layout, 0); }

Type guard

const hasColumns = (l: Layout): l is Layout & { columns: NonNullable<Layout["columns"]> } =>
    Array.isArray(l.columns) && l.columns.length > 0;

Try / catch

try {
    const col = getPosInLayout(layout, 0);
} catch (e) {
    if (e instanceof Error && e.message === "Attempted to get position on empty layout") {
        layout = createDefaultLayout(); // re-initialize
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling getPosInLayout with a layout object whose .columns property is undefined or null — e.g. before the layout state has been initialized, after a layout was cleared, or when passing a malformed/default Layout object.

Common situations: Persisted layout data missing the columns field (schema/version drift in saved settings); calling layout helpers during component mount before state initialization; passing an empty object cast as Layout.

Related errors


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/cdda174ee55acda8. Report an issue: GitHub.