GROQ query showing "[object Object]" instead of string - expected ']' error
I am trying to groq (what i thought was) a simple array of projects
`*[_type == "projects"]`DM ME FOR URL PLS
but I notice that my api version is like 2021-10-21 like the docs. not sure how to ensure it says up to date on my side?
also not sure why it's working there and not in my groq.
here's how I call it
try {
const domains = await sanity.fetch(await getProjectDomains());
console.log(domains);
} catch (error) {
console.error(error);
}ClientError: expected ']' following array body
at onResponse (node_modules/@sanity/client/lib/http/request.js:28:13)
at applyMiddleware (node_modules/get-it/lib-node/util/middlewareReducer.js:10:15)
at onResponse (node_modules/get-it/lib-node/index.js:80:22)
at node_modules/get-it/lib-node/index.js:50:55
at callback (node_modules/get-it/lib-node/request/node-request.js:67:46)
at node_modules/get-it/lib-node/request/node-request.js:156:14
at DestroyableTransform.<anonymous> (node_modules/simple-concat/index.js:8:13)
at Object.onceWrapper (node:events:509:28)
at DestroyableTransform.emit (node:events:402:35)
at DestroyableTransform.emit (node:domain:475:12) {
response: {
body: { error: [Object] },
url: 'DM ME',
method: 'GET',
headers: {
'content-type': 'application/json; charset=utf-8',
'content-length': '122',
'x-ratelimit-limit-second': '500',
'ratelimit-limit': '500',
'ratelimit-remaining': '499',
'ratelimit-reset': '1',
'x-ratelimit-remaining-second': '499',
'x-sanity-shard': 'gcp-eu-w1-01-prod-1028',
'x-served-by': 'gradient-query-7566c8dfb4-9lk2l',
date: 'Fri, 03 Jun 2022 19:32:04 GMT',
vary: 'Origin',
xkey: 'project-PROD_ID, project-PROD_ID-production',
via: '1.1 google',
'alt-svc': 'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000',
connection: 'close'
},
statusCode: 400,
statusMessage: 'Bad Request'
},
statusCode: 400,
responseBody: '{\n' +
' "error": {\n' +
` "description": "expected ']' following array body",\n` +
' "end": 14,\n' +
' "query": "[object Object]",\n' +
' "type": "queryParseError"\n' +
' }\n' +
'}',
details: {
description: "expected ']' following array body",
end: 14,
query: '[object Object]',
type: 'queryParseError'
}
}Looking at your error, I can see the problem! The key clue is in the error details: 'query': '[object Object]'. This means you're passing an object to sanity.fetch() instead of a GROQ query string.
The issue is in this line:
const domains = await sanity.fetch(await getProjectDomains());The fetch() method expects a string like '*[_type == "projects"]', but getProjectDomains() is returning an object. When JavaScript tries to convert that object to a string, it becomes "[object Object]", which is invalid GROQ syntax - hence the parse error.
To fix this, either:
- Pass the query string directly:
const domains = await sanity.fetch('*[_type == "projects"]');- Or make sure
getProjectDomains()returns a string:
function getProjectDomains() {
return '*[_type == "projects"]'; // Return the string, not an object
}
const domains = await sanity.fetch(getProjectDomains());
// No await needed unless getProjectDomains is actually asyncRegarding your API version question:
The apiVersion: '2021-10-21' you're seeing is totally fine! Sanity uses date-based API versioning to ensure compatibility. You set this when creating your client:
import {createClient} from '@sanity/client'
const sanity = createClient({
projectId: 'your-project-id',
dataset: 'production',
apiVersion: '2021-10-21', // Any date works - this locks API behavior
useCdn: true
})You can use any date like '2024-01-01' or '2023-05-03'. The date locks in the API behavior from that point, protecting you from breaking changes. The most recent version is 2025-02-19 which changed the default perspective from raw to published.
The Vision tool might show a different version, but that's just its own configuration - it doesn't affect your code. Your error is purely about passing an object instead of a string to fetch().
Show original thread6 replies
Was this answer helpful?
Sanity – Build the way you think, not the way your CMS thinks
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.