windmill-labs/windmill · error · Error
Invalid subgrid selected, the parent has no subgrids: ${key}
Error message
Invalid subgrid selected, the parent has no subgrids: ${key}, parent: ${JSON.stringify(parent)} What it means
Windmill's app editor throws this when a component is inserted into a subgrid identified by `key`, but the parent grid item stored in `app.grid`/`app.subgrids` cannot be found or has no `numberOfSubgrids` defined. It is a data-integrity guard in `insertNewGridItem` (frontend/src/lib/components/apps/editor/appUtils.ts) ensuring subgrid keys referenced in `app.subgrids` always point to a real parent component that declares subgrids.
Source
Thrown at frontend/src/lib/components/apps/editor/appUtils.ts:573
app.subgrids = {}
}
// We only want to set subgrids when we are not moving
if (!keepId || keepSubgrids) {
for (let i = 0; i < (data.numberOfSubgrids ?? 0); i++) {
app.subgrids[`${id}-${i}`] = []
}
}
const key = focusedGrid
? `${focusedGrid?.parentComponentId}-${focusedGrid?.subGridIndex ?? 0}`
: undefined
if (key && app.subgrids[key] === undefined) {
let parent = findGridItemById(app.grid, app.subgrids, key)?.data
let subgrids = parent?.numberOfSubgrids
if (subgrids === undefined) {
throw Error(
`Invalid subgrid selected, the parent has no subgrids: ${key}, parent: ${JSON.stringify(
parent
)}`
)
}
if (
focusedGrid?.subGridIndex &&
(focusedGrid?.subGridIndex < 0 || focusedGrid?.subGridIndex >= subgrids)
) {
throw Error(`Invalid subgrid selected: ${key}, max subgrids: ${subgrids}`)
}
// If ever the subgrid is undefined, we want to make sure it is defined
app.subgrids[key] = []
}
let grid = focusedGrid ? app.subgrids[key!] : app.grid
const newItem = createNewGridItem(View on GitHub (pinned to e474e8803c)
Solutions
- Re-select the target container in the editor so `focusedGrid.key` points to an existing component with numberOfSubgrids > 0 before inserting
- Check that the component id used as subgrid key still exists in app.grid (it may have been deleted or its id changed)
- If migrating/patching app JSON, regenerate subgrid keys from the current grid tree instead of reusing stale ones
- Wrap programmatic insertions in a guard that calls findGridItemById and checks numberOfSubgrids !== undefined first
Example fix
// before
await insertNewGridItem(app, 'stale-component-id', ...)
// after
const parent = findGridItemById(app.grid, app.subgrids, key)
if (parent?.data?.numberOfSubgrids !== undefined) {
await insertNewGridItem(app, key, ...)
} Defensive patterns
Strategy: validation
Validate before calling
import { findGridItemById } from '$lib/components/apps/editor/appUtils'
function canInsertIntoSubgrid(app, key) {
if (!key || app.subgrids[key] !== undefined) return true
const parent = findGridItemById(app.grid, app.subgrids, key)
return parent?.data?.numberOfSubgrids !== undefined
} Type guard
function isSubgridParent(item): item is GridItem & { data: { numberOfSubgrids: number } } {
return typeof item?.data?.numberOfSubgrids === 'number'
} Try / catch
try {
insertNewGridItem(app, key, item)
} catch (e) {
if (String(e.message).startsWith('Invalid subgrid selected')) {
toast.error('Target container no longer exists; select a valid grid container')
} else throw e
} Prevention
- Always resolve the key via findGridItemById and check numberOfSubgrids before inserting
- Delete child subgrid references when removing a container component
- Avoid hand-editing app JSON; use the editor so subgrid keys stay in sync
- Regenerate subgrid keys when copy/pasting components across apps
When it happens
Trigger: Calling insertNewGridItem (directly or via newItem, setUpTopBarComponentContent, handlePaste, moveComponentBetweenSubgrids, moveToRoot) with a `key` where `app.subgrids[key] === undefined` AND `findGridItemById(app.grid, app.subgrids, key)?.data.numberOfSubgrids` is undefined — i.e. the key refers to a deleted/renamed component, or a component that is not a grid-with-subgrids container.
Common situations: Pasting a copied component whose focusedGrid key references a container that was deleted; app JSON edited by hand or by a stale script referencing an old component id; moving a component into a subgrid of a plain (non-container) component; race where the parent component was removed between selection and insertion.
Related errors
- Invalid subgrid selected: ${key}, max subgrids: ${subgrids}
- '/wmill.d.ts' is generated automatically. Edit backend runna
- Frontend file '${target.path}' not found.
- Backend runnable '${target.key}' not found.
- '${target.path}' points to backend runnable '${target.key}',
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/42bd1d020f580caf.
Report an issue: GitHub.