windmill-labs/windmill · error

Table name is required

Error message

Table name is required

What it means

makeInsertQuery requires a non-empty table name because it interpolates the table identifier directly into `INSERT INTO ${table}`. An empty string would produce invalid SQL ('INSERT INTO (…)'), so the builder fails fast with 'Table name is required'. This is a guard against misconfigured table-state in the dbtable component.

Source

Thrown at frontend/src/lib/components/apps/components/display/dbtable/queries/insert.ts:94

			throw new Error(`Column ${column.field} is not nullable and has no default value`)
		}

		if (!userDefaultValue && !dbDefaultValue) {
			// Should be omitted if it's an identity column and we have no default value
			return column.isidentity !== ColumnIdentity.No
		}

		// Should be omitted if the user had not provided a default value and the database has a default value
		return !userDefaultValue && dbDefaultValue
	} else if (column.isnullable === 'YES') {
		return !userDefaultValue
	}

	return false
}

export function makeInsertQuery(table: string, columns: ColumnDef[], dbType: DbType) {
	if (!table) throw new Error('Table name is required')

	const columnsInsert = columns.filter(
		(x) => !x.hideInsert && !(dbType == 'postgresql' && x.defaultvalue?.startsWith('nextval('))
	)
	const columnsDefault = columns.filter((c) => !shouldOmitColumnInInsert(c))
	const allInsertColumns = columnsInsert.concat(columnsDefault)

	let query = buildParameters(columnsInsert, dbType)

	query += '\n'

	const shouldInsertComma = columnsDefault.length > 0
	const columnNames = formatColumnNames(allInsertColumns)
	const insertValues = formatInsertValues(columnsInsert, dbType)
	const defaultValues = formatDefaultValues(columnsDefault)
	const commaOrEmpty = shouldInsertComma ? ', ' : ''
	const valuesStr = `${insertValues}${commaOrEmpty}${defaultValues}`

View on GitHub (pinned to e474e8803c)

Solutions

  1. Ensure a table is selected before invoking the insert flow; disable the insert UI while table is empty.
  2. Default the table from state/URL params and guard the call site: only build the query when table is truthy.
  3. Fix the saved app config so the table name is statically set if it was intended to be constant.

Example fix

// before
const input = getInsertInput(dbInput, table, columns)
// after
if (!table) throw new Error('Select a table before inserting rows')
const input = getInsertInput(dbInput, table, columns)
Defensive patterns

Strategy: validation

Validate before calling

if (typeof table !== 'string' || !table.trim()) {
  throw new Error('Select a table before inserting rows')
}

Type guard

const hasTable = (t: unknown): t is string =>
  typeof t === 'string' && t.trim().length > 0

Try / catch

try {
  return getInsertInput(dbInput, table, columns)
} catch (e) {
  if (e instanceof Error && e.message === 'Table name is required') {
    showToast('Select a table first')
    return null
  }
  throw e
}

Prevention

When it happens

Trigger: Calling makeInsertQuery (via getInsertInput/query) with table === '' — e.g. the table editor rendered before a table was selected, state loss on refresh, or a saved app whose table binding evaluated to empty.

Common situations: User opens the insert dialog of a Database Studio app before picking a table; the table name comes from a variable/URL param that is undefined at build time; app state was saved without a table selection.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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