{"record":{"id":"cdda174ee55acda8","repo":"BabylonJS/Babylon.js","slug":"attempted-to-get-position-on-empty-layout","errorCode":null,"errorMessage":"Attempted to get position on empty layout","messagePattern":"Attempted to get position on empty layout","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/dev/sharedUiComponents/src/components/layout/utils.ts","lineNumber":13,"sourceCode":"import { type Layout, type LayoutColumn, type LayoutTabsRow } from \"./types\";\r\n\r\n/**\r\n * Given a column and row number in the layout, return the corresponding column/row\r\n * @param layout\r\n * @param column\r\n * @param row\r\n * @returns\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r\nexport const getPosInLayout = (layout: Layout, column: number, row?: number): LayoutColumn | LayoutTabsRow => {\r\n    if (!layout.columns) {\r\n        throw new Error(\"Attempted to get position on empty layout\");\r\n    }\r\n    const columnLayout = layout.columns[column];\r\n    if (!columnLayout) {\r\n        throw new Error(\"Attempted to get an invalid layout column\");\r\n    }\r\n    if (row === undefined) {\r\n        return columnLayout;\r\n    }\r\n    return columnLayout.rows[row];\r\n};\r\n\r\n/**\r\n * Remove a row in position row, column from the layout, and redistribute heights of remaining rows\r\n * @param layout\r\n * @param column\r\n * @param row\r\n */\r\n// eslint-disable-next-line @typescript-eslint/naming-convention\r","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/sharedUiComponents/src/components/layout/utils.ts#L1-L31","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Initialize layout.columns (e.g. layout.columns = [ ... ]) before calling getPosInLayout","Guard the call: check layout?.columns?.length before invoking","Load a valid default layout when stored/parsed layout data lacks columns (validate on JSON.parse)","Wrap the call in try/catch and fall back to a default column"],"exampleFix":"// before\nconst col = getPosInLayout(loadedLayout, 0); // loadedLayout.columns is undefined -> throws\n// after\nconst col = loadedLayout.columns ? getPosInLayout(loadedLayout, 0) : defaultLayout.columns[0];","handlingStrategy":"validation","validationCode":"function hasColumns(layout: Layout): layout is Layout & { columns: LayoutColumn[] } {\n    return Array.isArray(layout.columns) && layout.columns.length > 0;\n}\n// usage\nif (hasColumns(layout)) { const col = getPosInLayout(layout, 0); }","typeGuard":"const hasColumns = (l: Layout): l is Layout & { columns: NonNullable<Layout[\"columns\"]> } =>\n    Array.isArray(l.columns) && l.columns.length > 0;","tryCatchPattern":"try {\n    const col = getPosInLayout(layout, 0);\n} catch (e) {\n    if (e instanceof Error && e.message === \"Attempted to get position on empty layout\") {\n        layout = createDefaultLayout(); // re-initialize\n    } else { throw e; }\n}","preventionTips":["Always initialize layout.columns before invoking layout helpers","Validate layout JSON loaded from persistence (ensure columns exists) before applying it","Avoid passing freshly constructed empty Layout objects to helper functions","Sequence UI code so layout state is initialized before any pane-position lookups"],"tags":["ui","layout","shared-ui","state"],"backgroundTag":"empty-layout-state","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}