CherryHQ/cherry-studio · error · Error
Invalid response format from Dify API: ${JSON.stringify(sear
Error message
Invalid response format from Dify API: ${JSON.stringify(searchResponse)} What it means
Generic Error thrown by DifyKnowledgeServer.performSearchKnowledge when the parsed JSON response is null/falsy or does not contain a 'records' array. This guards against unexpected response shapes — the HTTP status was 200 but the body does not conform to the DifySearchKnowledgeResponse contract. The entire response is JSON-stringified into the error message for diagnosis.
Source
Thrown at src/main/ai/mcp/servers/difyKnowledge.ts:216
retrieval_model: {
top_k: topK,
// will be error if not set
search_method: 'semantic_search',
reranking_enable: false,
score_threshold_enabled: false
}
})
})
if (!response.ok) {
const errorText = await response.text()
throw new Error(`API request failed, status code ${response.status}: ${errorText}`)
}
const searchResponse: DifySearchKnowledgeResponse = await response.json()
if (!searchResponse || !Array.isArray(searchResponse.records)) {
throw new Error(`Invalid response format from Dify API: ${JSON.stringify(searchResponse)}`)
}
const header = `### Query: ${query}\n\n`
let body: string
if (searchResponse.records.length === 0) {
body = 'No results found.'
} else {
const resultsText = searchResponse.records
.map((record, index) => {
const docName = record.segment.document?.name || 'Unknown Document'
const content = record.segment.content.trim()
const score = record.score
const keywords = record.segment.keywords || []
let resultEntry = `#### ${index + 1}. ${docName} (Relevant Score: ${(score * 100).toFixed(1)}%)`
resultEntry += `\n${content}`
if (keywords.length > 0) {View on GitHub (pinned to 726446b54c)
Solutions
- Log and inspect the full JSON.stringify(searchResponse) to identify the actual shape.
- Verify the Dify API version matches the expected response contract.
- If a proxy alters responses, configure it to pass through the Dify body unchanged.
- Handle the malformed response gracefully with a user-friendly message.
Example fix
// before
if (!searchResponse || !Array.isArray(searchResponse.records)) {
throw new Error(`Invalid response format from Dify API: ${JSON.stringify(searchResponse)}`)
}
// after
if (!searchResponse || !Array.isArray(searchResponse.records)) {
logger.error('Unexpected Dify retrieve response shape', { response: searchResponse })
return errorResult('Knowledge search returned an unexpected response format. Check Dify API version compatibility.')
} Defensive patterns
Strategy: type-guard
Validate before calling
const searchResponse: unknown = await response.json()
if (
typeof searchResponse !== 'object' ||
searchResponse === null ||
!Array.isArray((searchResponse as any).records)
) {
logger.error('Unexpected Dify retrieve response', { body: searchResponse })
return { content: [{ type: 'text', text: 'Knowledge search returned an unexpected response format.' }], isError: true }
} Type guard
function isDifySearchResponse(res: unknown): res is { records: Array<{ segment: { content: string; document?: { name?: string }; keywords?: string[] }; score: number }> } {
return (
typeof res === 'object' &&
res !== null &&
'records' in res &&
Array.isArray((res as any).records)
)
} Try / catch
try {
return await performSearchKnowledge(id, query, topK, difyKey, apiHost)
} catch (e) {
const msg = e instanceof Error ? e.message : String(e)
if (msg.includes('Invalid response format')) {
// log full body and return a user-friendly error
return { content: [{ type: 'text', text: 'Unexpected API response. Check Dify version compatibility.' }], isError: true }
}
throw e
} Prevention
- Log the full response body when the shape is unexpected to diagnose version mismatches.
- Verify the Dify API version matches the expected response contract.
- Use a runtime type guard before accessing .records to fail gracefully.
When it happens
Trigger: The Dify /retrieve endpoint returns 200 with a body that is null, an empty object, or has a different structure (e.g., an error object without the records field). This can happen with API version mismatches, non-standard Dify forks, or proxy/gateway responses that alter the body.
Common situations: Dify API version returns a different response schema; a reverse proxy injects a wrapper object; the endpoint returned an HTML error page that happened to parse as JSON; the Dify instance is a fork with a modified retrieve response.
Related errors
- QQ API request failed ${endpoint}: HTTP ${response.status} -
- Brave API error: ${response.status} ${response.statusText}\n
- Brave API error: ${webResponse.status} ${webResponse.statusT
- DifyKnowledgeServer requires at least one argument
- Invalid arguments:\n${errorDetails}
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/fec478dfbf4266a0.
Report an issue: GitHub.