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

  1. Re-select the target container in the editor so `focusedGrid.key` points to an existing component with numberOfSubgrids > 0 before inserting
  2. Check that the component id used as subgrid key still exists in app.grid (it may have been deleted or its id changed)
  3. If migrating/patching app JSON, regenerate subgrid keys from the current grid tree instead of reusing stale ones
  4. 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

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


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/42bd1d020f580caf. Report an issue: GitHub.