{"record":{"id":"61de7fe60be37aee","repo":"outline/outline","slug":"sort-field-must-be-one-of-title-index","errorCode":null,"errorMessage":"Sort field must be one of title,index","messagePattern":"Sort field must be one of title,index","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"server/models/Collection.ts","lineNumber":291,"sourceCode":"  @Column({\n    type: DataType.JSONB,\n    validate: {\n      isSort(value: CollectionSort) {\n        if (\n          typeof value !== \"object\" ||\n          !value.direction ||\n          !value.field ||\n          Object.keys(value).length !== 2\n        ) {\n          throw new Error(\"Sort must be an object with field,direction\");\n        }\n\n        if (![\"asc\", \"desc\"].includes(value.direction)) {\n          throw new Error(\"Sort direction must be one of asc,desc\");\n        }\n\n        if (![\"title\", \"index\"].includes(value.field)) {\n          throw new Error(\"Sort field must be one of title,index\");\n        }\n      },\n    },\n  })\n  sort: CollectionSort;\n\n  /** Whether the collection is archived, and if so when. */\n  @IsDate\n  @Column(DataType.DATE)\n  archivedAt: Date | null;\n\n  /** The minimum permission level required to manage templates in this collection. */\n  @IsIn([[CollectionPermission.Admin, CollectionPermission.ReadWrite]])\n  @Default(CollectionPermission.Admin)\n  @Column(DataType.STRING)\n  templateManagement: CollectionPermission;\n\n  /** Allows the configuration of commenting per collection. */","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/outline/outline/blob/935a44d4c003429645a956141b2c4eb695f34b6e/server/models/Collection.ts#L273-L309","documentation":"The third leg of the Collection.sort validator: field must be one of 'title' or 'index'. Any other field name (e.g. 'createdAt', 'name') is rejected even if the shape and direction are valid.","triggerScenarios":"Setting sort.field to anything other than 'title' or 'index', e.g. when a client tries to sort by a custom attribute.","commonSituations":"Assuming arbitrary fields are sortable; carrying over a sort field from another product; UI exposing columns the backend doesn't support sorting by.","solutions":["Use only 'title' or 'index' as the sort field.","If you need other sort criteria, extend the validator allow-list and ensure the DB query supports it.","Constrain the UI sort dropdown to the supported fields."],"exampleFix":"// before\nsort: { field: 'createdAt', direction: 'asc' }\n\n// after\nsort: { field: 'title', direction: 'asc' }","handlingStrategy":"validation","validationCode":"const ALLOWED = ['title', 'index'] as const;\nif (!ALLOWED.includes(sort.field)) {\n  throw new ValidationError(`sort.field must be one of ${ALLOWED.join(',')}`);\n}","typeGuard":"const isSortField = (f: unknown): f is 'title' | 'index' =>\n  f === 'title' || f === 'index';","tryCatchPattern":null,"preventionTips":["Restrict the sort dropdown to title and index.","Extend the validator (and the query layer) if you add new sortable fields.","Validate at the API boundary to give a clean 400."],"tags":["server","models","collection","validation","sort"],"backgroundTag":null,"analyzedSha":"935a44d4c003429645a956141b2c4eb695f34b6e","analyzedAt":"2026-08-12T22:40:11.882Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}