CherryHQ/cherry-studio · error · Error

API request failed, status code ${response.status}: ${errorT

Error message

API request failed, status code ${response.status}: ${errorText}

What it means

Generic Error thrown by DifyKnowledgeServer.performListKnowledges when the GET /datasets request to the Dify API returns a non-2xx status. The error includes the status code and raw response body. It is caught by performListKnowledges' own try-catch and returned as an MCP isError response.

Source

Thrown at src/main/ai/mcp/servers/difyKnowledge.ts:147

          isError: true
        }
      }
    })
  }

  private async performListKnowledges(difyKey: string, apiHost: string): Promise<McpResponse> {
    try {
      const url = `${apiHost.replace(/\/$/, '')}/datasets`
      const response = await net.fetch(url, {
        method: 'GET',
        headers: {
          Authorization: `Bearer ${difyKey}`
        }
      })

      if (!response.ok) {
        const errorText = await response.text()
        throw new Error(`API request failed, status code ${response.status}: ${errorText}`)
      }

      const apiResponse = await response.json()

      const knowledges: DifyListKnowledgeResponse[] =
        apiResponse?.data?.map((item: any) => ({
          id: item.id,
          name: item.name,
          description: item.description || ''
        })) || []

      const listText =
        knowledges.length > 0
          ? knowledges.map((k) => `- **${k.name}** (ID: ${k.id})\n  ${k.description || 'No Description'}`).join('\n')
          : '- No knowledges found.'

      const formattedText = `### Available Knowledge Bases:\n\n${listText}`

View on GitHub (pinned to 726446b54c)

Solutions

  1. Verify DIFY_KEY is valid and has dataset read permissions (401/403).
  2. Confirm the apiHost URL is correct and ends with the API base path (e.g., /v1).
  3. Check that the Dify instance is running and reachable.
  4. Inspect errorText for the Dify-specific error message.

Example fix

// before
if (!response.ok) {
  const errorText = await response.text()
  throw new Error(`API request failed, status code ${response.status}: ${errorText}`)
}

// after
if (!response.ok) {
  const errorText = await response.text()
  if (response.status === 401) {
    return errorResult('DIFY_KEY is invalid or expired. Please reconfigure the API key.')
  }
  throw new Error(`API request failed, status code ${response.status}: ${errorText}`)
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!difyKey) {
  throw new Error('DIFY_KEY is not set — cannot list knowledge bases')
}
if (!apiHost || !/^https?:\/\//.test(apiHost)) {
  throw new Error('Invalid Dify apiHost — must be a full URL')
}

Try / catch

try {
  return await performListKnowledges(difyKey, apiHost)
} catch (e) {
  const msg = e instanceof Error ? e.message : String(e)
  if (msg.includes('status code 401') || msg.includes('status code 403')) {
    return { content: [{ type: 'text', text: 'DIFY_KEY is invalid or expired. Please reconfigure.' }], isError: true }
  }
  throw e
}

Prevention

When it happens

Trigger: GET {apiHost}/datasets with a Bearer token (DIFY_KEY) returns non-ok: 401/403 (invalid/expired key), 404 (wrong apiHost path), 5xx (Dify server error).

Common situations: DIFY_KEY is invalid, expired, or lacks knowledge-base read permissions; apiHost is wrong (missing /v1 suffix, trailing path mismatch); Dify instance is down or unreachable; network proxy returns an error.

Related errors


AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12). Data as JSON: /api/errors/9f19dcac90e83db5. Report an issue: GitHub.