n8n-io/n8n · error · TypeORMError

SelectQueryBuilder.addOrderBy "nulls" can accept only "NULLS

Error message

SelectQueryBuilder.addOrderBy "nulls" can accept only "NULLS FIRST" and "NULLS LAST" values.

What it means

SelectQueryBuilder.orderBy validates the nulls argument and throws TypeORMError when it is neither 'NULLS FIRST' nor 'NULLS LAST' (and not undefined). This guards against emitting invalid NULLS handling in the generated SQL.

Source

Thrown at packages/@n8n/typeorm/src/query-builder/SelectQueryBuilder.ts:1277

	 */
	orderBy(order: OrderByCondition): this;

	/**
	 * Sets ORDER BY condition in the query builder.
	 * If you had previously ORDER BY expression defined,
	 * calling this function will override previously set ORDER BY conditions.
	 */
	orderBy(
		sort?: string | OrderByCondition,
		order: 'ASC' | 'DESC' = 'ASC',
		nulls?: 'NULLS FIRST' | 'NULLS LAST',
	): this {
		if (order !== undefined && order !== 'ASC' && order !== 'DESC')
			throw new TypeORMError(
				`SelectQueryBuilder.addOrderBy "order" can accept only "ASC" and "DESC" values.`,
			);
		if (nulls !== undefined && nulls !== 'NULLS FIRST' && nulls !== 'NULLS LAST')
			throw new TypeORMError(
				`SelectQueryBuilder.addOrderBy "nulls" can accept only "NULLS FIRST" and "NULLS LAST" values.`,
			);

		if (sort) {
			if (typeof sort === 'object') {
				this.expressionMap.orderBys = sort as OrderByCondition;
			} else {
				if (nulls) {
					this.expressionMap.orderBys = {
						[sort as string]: { order, nulls },
					};
				} else {
					this.expressionMap.orderBys = { [sort as string]: order };
				}
			}
		} else {
			this.expressionMap.orderBys = {};
		}

View on GitHub (pinned to 5ac6606e81)

Solutions

  1. Normalize: const nulls = req.query.nulls === 'last' ? 'NULLS LAST' : req.query.nulls === 'first' ? 'NULLS FIRST' : undefined.
  2. Whitelist before calling; throw a UserError for anything else.
  3. Validate the query string with an enum schema.

Example fix

// before
qb.orderBy('user.name', 'ASC', req.query.nulls);
// after
const nulls = req.query.nulls === 'last' ? 'NULLS LAST'
             : req.query.nulls === 'first' ? 'NULLS FIRST'
             : undefined;
qb.orderBy('user.name', 'ASC', nulls);
Defensive patterns

Strategy: validation

Validate before calling

function normalizeNulls(input: unknown): 'NULLS FIRST' | 'NULLS LAST' | undefined {
  if (input == null) return undefined;
  const v = String(input).toUpperCase();
  if (v === 'NULLS FIRST' || v === 'FIRST') return 'NULLS FIRST';
  if (v === 'NULLS LAST' || v === 'LAST') return 'NULLS LAST';
  return undefined;
}

Type guard

function isNullsDir(value: unknown): value is 'NULLS FIRST' | 'NULLS LAST' {
  return value === 'NULLS FIRST' || value === 'NULLS LAST';
}

Prevention

When it happens

Trigger: qb.orderBy('user.name','ASC', req.query.nulls) where the param is 'first'/'FIRST'/'nulls first' (lowercase/abbreviated); passing a UI enum value verbatim.

Common situations: Frontend dropdown value 'First'/'Last' fed straight to the builder; refactor that drops the NULLS_ prefix.

Related errors


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/b28d4f7ad954d6cd. Report an issue: GitHub.