{"record":{"id":"baf277bff83109cb","repo":"windmill-labs/windmill","slug":"invalid-subgrid-selected-key-max-subgrids","errorCode":null,"errorMessage":"Invalid subgrid selected: ${key}, max subgrids: ${subgrids}","messagePattern":"Invalid subgrid selected: (.+?), max subgrids: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/apps/editor/appUtils.ts","lineNumber":583,"sourceCode":"\tconst key = focusedGrid\n\t\t? `${focusedGrid?.parentComponentId}-${focusedGrid?.subGridIndex ?? 0}`\n\t\t: undefined\n\n\tif (key && app.subgrids[key] === undefined) {\n\t\tlet parent = findGridItemById(app.grid, app.subgrids, key)?.data\n\t\tlet subgrids = parent?.numberOfSubgrids\n\t\tif (subgrids === undefined) {\n\t\t\tthrow Error(\n\t\t\t\t`Invalid subgrid selected, the parent has no subgrids: ${key}, parent: ${JSON.stringify(\n\t\t\t\t\tparent\n\t\t\t\t)}`\n\t\t\t)\n\t\t}\n\t\tif (\n\t\t\tfocusedGrid?.subGridIndex &&\n\t\t\t(focusedGrid?.subGridIndex < 0 || focusedGrid?.subGridIndex >= subgrids)\n\t\t) {\n\t\t\tthrow Error(`Invalid subgrid selected: ${key}, max subgrids: ${subgrids}`)\n\t\t}\n\t\t// If ever the subgrid is undefined, we want to make sure it is defined\n\t\tapp.subgrids[key] = []\n\t}\n\n\tlet grid = focusedGrid ? app.subgrids[key!] : app.grid\n\n\tconst newItem = createNewGridItem(\n\t\tgrid,\n\t\tid,\n\t\tdata,\n\t\tcolumns,\n\t\tinitialPosition,\n\t\trecOverride,\n\t\tfixed,\n\t\tshouldNotFindSpace\n\t)\n\tgrid.push(newItem)","sourceCodeStart":565,"sourceCodeEnd":601,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/apps/editor/appUtils.ts#L565-L601","documentation":"Thrown by `insertNewGridItem` when the selected `subGridIndex` on the focused grid item is negative or >= the parent's `numberOfSubgrids`. After this check the code initializes `app.subgrids[key] = []` so the index bound comes from the parent's declared subgrid count.","triggerScenarios":"Inserting into a subgrid via newItem/handlePaste/moveComponentBetweenSubgrids/moveToRoot where focusedGrid.subGridIndex is out of [0, numberOfSubgrids) — e.g. subGridIndex 2 on a parent with 2 subgrids (valid indexes 0 and 1), a negative index, or an index left over from a component whose subgrid count shrank.","commonSituations":"Programmatic component insertion with a hardcoded subGridIndex; pasting into a copied component whose source parent had more subgrids than the destination; app JSON patched to reduce numberOfSubgrids while children still reference the old indexes.","solutions":["Set focusedGrid.subGridIndex to a value in [0, numberOfSubgrids) of the parent before inserting","Verify the parent component's numberOfSubgrids matches your intended index (e.g. index 1 requires numberOfSubgrids >= 2)","Fix stale app JSON so subGridIndex values are consistent with current numberOfSubgrids","Clamp or reset subGridIndex to 0 when the destination component is unknown"],"exampleFix":"// before\nfocusedGrid.subGridIndex = 3 // parent has numberOfSubgrids: 2\n// after\nconst max = findGridItemById(app.grid, app.subgrids, key)?.data?.numberOfSubgrids ?? 0\nfocusedGrid.subGridIndex = Math.min(Math.max(focusedGrid.subGridIndex ?? 0, 0), Math.max(max - 1, 0))","handlingStrategy":"validation","validationCode":"function isValidSubgridIndex(app, key, subGridIndex) {\n  const parent = findGridItemById(app.grid, app.subgrids, key)\n  const max = parent?.data?.numberOfSubgrids ?? 0\n  return Number.isInteger(subGridIndex) && subGridIndex >= 0 && subGridIndex < max\n}","typeGuard":"function hasValidSubGridIndex(g): g is typeof g & { subGridIndex: number } {\n  return typeof g?.subGridIndex === 'number' && g.subGridIndex >= 0\n}","tryCatchPattern":"try {\n  insertNewGridItem(app, key, item)\n} catch (e) {\n  if (String(e.message).startsWith('Invalid subgrid selected:')) {\n    focusedGrid.subGridIndex = 0\n    insertNewGridItem(app, key, item)\n  } else throw e\n}","preventionTips":["Clamp subGridIndex to [0, numberOfSubgrids-1] before insert/move/paste","Recompute subGridIndex after changing a component's numberOfSubgrids","Never hardcode subgrid indexes in scripts; read the parent's count first"],"tags":["app-editor","subgrids","index-out-of-range"],"backgroundTag":"index-out-of-range","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}