{"record":{"id":"748dfcd1518b3113","repo":"gatsbyjs/gatsby","slug":"nodemodel-findone-does-not-support-sorting-use","errorCode":null,"errorMessage":"nodeModel.findOne() does not support sorting. Use nodeModel.findAll({ query: { limit: 1 } }) instead.","messagePattern":"nodeModel\\.findOne\\(\\) does not support sorting\\. Use nodeModel\\.findAll\\((.+?) \\}\\) instead\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/gatsby/src/schema/node-model.js","lineNumber":379,"sourceCode":"   *\n   * @param {*} args\n   * @param {Object} args.query Query arguments (e.g. `filter`). Doesn't support `sort`, `limit`, `skip`.\n   * @param {(string|GraphQLOutputType)} args.type Type\n   * @param {PageDependencies} [pageDependencies]\n   * @returns {Promise<Node>}\n   * @example\n   * // Get one node of type `MyType` by its title\n   * const node = await findOne({\n   *   type: `MyType`,\n   *   query: { filter: { title: { eq: `My Title` } } },\n   * })\n   */\n  async findOne(args, pageDependencies = {}) {\n    const { query = {} } = args\n    if (query.sort?.fields?.length > 0) {\n      // If we support sorting and return the first node based on sorting\n      // we'll have to always track connection not an individual node\n      throw new Error(\n        `nodeModel.findOne() does not support sorting. Use nodeModel.findAll({ query: { limit: 1 } }) instead.`\n      )\n    }\n    const { gqlType, entries } = await this._query({\n      ...args,\n      query: { ...query, skip: 0, limit: 1, sort: undefined },\n    })\n    const result = Array.from(entries)\n    const first = result[0] ?? null\n\n    if (!first) {\n      // Couldn't find matching node.\n      //  This leads to a state where data tracking for this query gets empty.\n      //  It means we will NEVER re-run this query on any data updates\n      //  (even if a new node matching this query is added at some point).\n      //  To workaround this, we have to add a connection tracking to re-run\n      //  the query whenever any node of this type changes.\n      pageDependencies.connectionType = gqlType.name","sourceCodeStart":361,"sourceCodeEnd":397,"githubUrl":"https://github.com/gatsbyjs/gatsby/blob/8b06340921ffdf23125a365b9c9923690cb62ce6/packages/gatsby/src/schema/node-model.js#L361-L397","documentation":"nodeModel.findOne resolves exactly one node and intentionally does not support sorting, because honoring a sort order would force Gatsby to track a connection (ordered set) rather than a single node. If args.query.sort.fields is non-empty, findOne throws and directs callers to findAll with limit:1.","triggerScenarios":"Calling nodeModel.findOne({ type, query: { filter: {...}, sort: { fields: ['date'], order: ['DESC'] } } }) inside a resolver, gatsby-node createResolvers, or a custom field extension.","commonSituations":"Porting findAll logic into findOne; resolver authors wanting 'the most recent X' via findOne.","solutions":["Replace findOne with findAll({ type, query: { filter, sort, limit: 1 } }) and read the first edge.","Drop the sort and select deterministically by filter (e.g. by id).","If sorting is essential, fetch via findAll and sort the returned array yourself."],"exampleFix":"// before\nconst node = await nodeModel.findOne({\n  type: `Article`,\n  query: { filter: { id: { eq } }, sort: { fields: [`publishedAt`], order: [`DESC`] } },\n})\n// after\nconst result = await nodeModel.findAll({\n  type: `Article`,\n  query: { filter: { id: { eq } }, sort: { fields: [`publishedAt`], order: [`DESC`] }, limit: 1 },\n})\nconst node = result.entries[0] ?? null","handlingStrategy":"validation","validationCode":"function findOneSafe(nodeModel, args) {\n  if (args.query?.sort?.fields?.length > 0) {\n    // findOne cannot sort; route to findAll\n    return nodeModel.findAll({ ...args, query: { ...args.query, limit: 1 } })\n      .then(r => r.entries[0] ?? null)\n  }\n  return nodeModel.findOne(args)\n}","typeGuard":"function queryHasSort(query = {}) {\n  return Array.isArray(query.sort?.fields) && query.sort.fields.length > 0\n}","tryCatchPattern":null,"preventionTips":["Treat findOne as unsorted by contract; if you need ordering use findAll with limit:1.","Wrap nodeModel calls in a helper that auto-routes sorted findOne to findAll.","Document resolver helpers to make the no-sort rule explicit."],"tags":["node-model","graphql","resolver"],"backgroundTag":null,"analyzedSha":"8b06340921ffdf23125a365b9c9923690cb62ce6","analyzedAt":"2026-08-13T02:36:21.405Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}