linshenkx/prompt-optimizer · error · Error
Garden suggestions response must be an object
Error message
Garden suggestions response must be an object
What it means
Thrown by fetchPromptGardenSuggestions when the suggestions endpoint returns HTTP 200 but the JSON body is not an object (e.g. an array, string, number, or null). The library parses the body and runs an isRecord check before reading data.items; any non-object payload fails fast with this error instead of producing a TypeError later.
Source
Thrown at packages/ui/src/utils/prompt-garden-suggestions.ts:170
const controller = new AbortController()
const timeout = setTimeout(() => controller.abort(), options.timeoutMs ?? DEFAULT_TIMEOUT_MS)
try {
const resp = await fetch(url, {
method: 'GET',
headers: {
Accept: 'application/json',
},
signal: controller.signal,
})
if (!resp.ok) {
throw new Error(`Garden suggestions request failed: ${resp.status}`)
}
const data = (await resp.json()) as unknown
if (!isRecord(data)) {
throw new Error('Garden suggestions response must be an object')
}
const items = Array.isArray(data.items)
? data.items
.map((item) => normalizeSuggestionItem(item, gardenBaseUrl))
.filter((item): item is PromptGardenSuggestionItem => Boolean(item))
: []
const browseUrl =
resolveGardenUrl(gardenBaseUrl, data.browseUrl) ||
buildFallbackBrowseUrl(gardenBaseUrl, options.mode)
const ttlSeconds =
typeof data.ttlSeconds === 'number' && Number.isFinite(data.ttlSeconds) && data.ttlSeconds > 0
? Math.floor(data.ttlSeconds)
: null
return {View on GitHub (pinned to 3e677b1d9f)
Solutions
- Inspect the actual response body (curl the endpoint) to see the real shape
- Upgrade/align the garden service and client versions so the response is { items: [...] }
- Fix backend serialization to always return an object with items (possibly empty array)
- Remove any proxy/rewrite rules that transform the response body
Example fix
// backend: return an object with items instead of a bare array
// before
return NextResponse.json(suggestions) // e.g. [{...}, {...}]
// after
return NextResponse.json({ items: suggestions }) Defensive patterns
Strategy: type-guard
Type guard
const isSuggestionsResponse = (data: unknown): data is { items: unknown[] } =>
typeof data === 'object' && data !== null && Array.isArray((data as { items?: unknown }).items) Try / catch
try {
const items = await fetchPromptGardenSuggestions(options)
} catch (error) {
if ((error as Error).message.includes('must be an object')) {
// endpoint/shape mismatch: log payload, fall back to empty suggestions
return []
}
throw error
} Prevention
- Contract-test the endpoint shape in CI against the deployed garden service
- Version the API and pin client/server versions together
- Treat shape errors as non-retryable bugs, not transient failures
When it happens
Trigger: Endpoint returns a JSON array, bare string/number, or null body; a proxy or gateway returning a JSON-encoded error string with 200; misrouted endpoint returning a different JSON shape.
Common situations: API version mismatch where the deployed garden returns a list instead of { items: [...] }; middleware or CDN intercepting and rewriting responses; backend returning null for an empty result set.
Related errors
- INVALID_RESPONSE_FORMAT
- INVALID_RESPONSE_FORMAT
- INVALID_RESPONSE_FORMAT
- Unsupported Garden response schema
- Unsupported Garden response schemaVersion
AI-assisted analysis of linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27).
Data as JSON: /api/errors/96949f535211593b.
Report an issue: GitHub.