gatsbyjs/gatsby · error
nodeModel.findOne() does not support sorting. Use nodeModel.
Error message
nodeModel.findOne() does not support sorting. Use nodeModel.findAll({ query: { limit: 1 } }) instead. What it means
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.
Source
Thrown at packages/gatsby/src/schema/node-model.js:379
*
* @param {*} args
* @param {Object} args.query Query arguments (e.g. `filter`). Doesn't support `sort`, `limit`, `skip`.
* @param {(string|GraphQLOutputType)} args.type Type
* @param {PageDependencies} [pageDependencies]
* @returns {Promise<Node>}
* @example
* // Get one node of type `MyType` by its title
* const node = await findOne({
* type: `MyType`,
* query: { filter: { title: { eq: `My Title` } } },
* })
*/
async findOne(args, pageDependencies = {}) {
const { query = {} } = args
if (query.sort?.fields?.length > 0) {
// If we support sorting and return the first node based on sorting
// we'll have to always track connection not an individual node
throw new Error(
`nodeModel.findOne() does not support sorting. Use nodeModel.findAll({ query: { limit: 1 } }) instead.`
)
}
const { gqlType, entries } = await this._query({
...args,
query: { ...query, skip: 0, limit: 1, sort: undefined },
})
const result = Array.from(entries)
const first = result[0] ?? null
if (!first) {
// Couldn't find matching node.
// This leads to a state where data tracking for this query gets empty.
// It means we will NEVER re-run this query on any data updates
// (even if a new node matching this query is added at some point).
// To workaround this, we have to add a connection tracking to re-run
// the query whenever any node of this type changes.
pageDependencies.connectionType = gqlType.nameView on GitHub (pinned to 8b06340921)
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.
Example fix
// before
const node = await nodeModel.findOne({
type: `Article`,
query: { filter: { id: { eq } }, sort: { fields: [`publishedAt`], order: [`DESC`] } },
})
// after
const result = await nodeModel.findAll({
type: `Article`,
query: { filter: { id: { eq } }, sort: { fields: [`publishedAt`], order: [`DESC`] }, limit: 1 },
})
const node = result.entries[0] ?? null Defensive patterns
Strategy: validation
Validate before calling
function findOneSafe(nodeModel, args) {
if (args.query?.sort?.fields?.length > 0) {
// findOne cannot sort; route to findAll
return nodeModel.findAll({ ...args, query: { ...args.query, limit: 1 } })
.then(r => r.entries[0] ?? null)
}
return nodeModel.findOne(args)
} Type guard
function queryHasSort(query = {}) {
return Array.isArray(query.sort?.fields) && query.sort.fields.length > 0
} Prevention
- 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.
When it happens
Trigger: Calling nodeModel.findOne({ type, query: { filter: {...}, sort: { fields: ['date'], order: ['DESC'] } } }) inside a resolver, gatsby-node createResolvers, or a custom field extension.
Common situations: Porting findAll logic into findOne; resolver authors wanting 'the most recent X' via findOne.
Related errors
- The "layout" argument is required for "${source.url}"
- BabelPluginRemoveGraphQLQueries: String interpolations are n
- BabelPluginRemoveGraphQLQueries: Unexpected empty graphql ta
- BabelPluginRemoveGraphQLQueries: GraphQL syntax error in que
- BabelPluginRemoveGraphQLQueries: the "${exportName}" export
AI-assisted analysis of gatsbyjs/gatsby@8b06340921 (2026-08-13).
Data as JSON: /api/errors/748dfcd1518b3113.
Report an issue: GitHub.