{"record":{"id":"b28d4f7ad954d6cd","repo":"n8n-io/n8n","slug":"selectquerybuilder-addorderby-nulls-can-accept-o","errorCode":null,"errorMessage":"SelectQueryBuilder.addOrderBy \"nulls\" can accept only \"NULLS FIRST\" and \"NULLS LAST\" values.","messagePattern":"SelectQueryBuilder\\.addOrderBy \"nulls\" can accept only \"NULLS FIRST\" and \"NULLS LAST\" values\\.","errorType":"exception","errorClass":"TypeORMError","httpStatus":null,"severity":"error","filePath":"packages/@n8n/typeorm/src/query-builder/SelectQueryBuilder.ts","lineNumber":1277,"sourceCode":"\t */\n\torderBy(order: OrderByCondition): this;\n\n\t/**\n\t * Sets ORDER BY condition in the query builder.\n\t * If you had previously ORDER BY expression defined,\n\t * calling this function will override previously set ORDER BY conditions.\n\t */\n\torderBy(\n\t\tsort?: string | OrderByCondition,\n\t\torder: 'ASC' | 'DESC' = 'ASC',\n\t\tnulls?: 'NULLS FIRST' | 'NULLS LAST',\n\t): this {\n\t\tif (order !== undefined && order !== 'ASC' && order !== 'DESC')\n\t\t\tthrow new TypeORMError(\n\t\t\t\t`SelectQueryBuilder.addOrderBy \"order\" can accept only \"ASC\" and \"DESC\" values.`,\n\t\t\t);\n\t\tif (nulls !== undefined && nulls !== 'NULLS FIRST' && nulls !== 'NULLS LAST')\n\t\t\tthrow new TypeORMError(\n\t\t\t\t`SelectQueryBuilder.addOrderBy \"nulls\" can accept only \"NULLS FIRST\" and \"NULLS LAST\" values.`,\n\t\t\t);\n\n\t\tif (sort) {\n\t\t\tif (typeof sort === 'object') {\n\t\t\t\tthis.expressionMap.orderBys = sort as OrderByCondition;\n\t\t\t} else {\n\t\t\t\tif (nulls) {\n\t\t\t\t\tthis.expressionMap.orderBys = {\n\t\t\t\t\t\t[sort as string]: { order, nulls },\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\tthis.expressionMap.orderBys = { [sort as string]: order };\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthis.expressionMap.orderBys = {};\n\t\t}","sourceCodeStart":1259,"sourceCodeEnd":1295,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/typeorm/src/query-builder/SelectQueryBuilder.ts#L1259-L1295","documentation":"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.","triggerScenarios":"qb.orderBy('user.name','ASC', req.query.nulls) where the param is 'first'/'FIRST'/'nulls first' (lowercase/abbreviated); passing a UI enum value verbatim.","commonSituations":"Frontend dropdown value 'First'/'Last' fed straight to the builder; refactor that drops the NULLS_ prefix.","solutions":["Normalize: const nulls = req.query.nulls === 'last' ? 'NULLS LAST' : req.query.nulls === 'first' ? 'NULLS FIRST' : undefined.","Whitelist before calling; throw a UserError for anything else.","Validate the query string with an enum schema."],"exampleFix":"// before\nqb.orderBy('user.name', 'ASC', req.query.nulls);\n// after\nconst nulls = req.query.nulls === 'last' ? 'NULLS LAST'\n             : req.query.nulls === 'first' ? 'NULLS FIRST'\n             : undefined;\nqb.orderBy('user.name', 'ASC', nulls);","handlingStrategy":"validation","validationCode":"function normalizeNulls(input: unknown): 'NULLS FIRST' | 'NULLS LAST' | undefined {\n  if (input == null) return undefined;\n  const v = String(input).toUpperCase();\n  if (v === 'NULLS FIRST' || v === 'FIRST') return 'NULLS FIRST';\n  if (v === 'NULLS LAST' || v === 'LAST') return 'NULLS LAST';\n  return undefined;\n}","typeGuard":"function isNullsDir(value: unknown): value is 'NULLS FIRST' | 'NULLS LAST' {\n  return value === 'NULLS FIRST' || value === 'NULLS LAST';\n}","tryCatchPattern":null,"preventionTips":["Map frontend enum values to the TypeORM constants at the API boundary.","Document that the literal must include the 'NULLS ' prefix.","Add a schema for the nulls query param."],"tags":["typeorm","select-query-builder","order-by","nulls","validation"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}