CherryHQ/cherry-studio · error · Error

Rerank response results must contain numeric index and relev

Error message

Rerank response results must contain numeric index and relevance_score

What it means

Thrown by downloadAndPersistImageUrls() when the remote generation succeeded and returned one or more URLs, but every single download+persistence attempt failed (files.length === 0). Each URL is fetched, base64-encoded, and turned into an internal file_entry via fileManager.createInternalEntry; if none survive, the job fails to avoid reporting a paid generation as an empty success. A partial failure (some succeeded) does NOT throw — it logs a warning and returns what it has.

Source

Thrown at packages/ai-sdk-provider/src/openai-compatible-reranking-model.ts:97

        body: rawValue
      }
    }
  }
}

function parseRerankResponse(body: unknown, documentCount: number): RerankRanking {
  const results = (body as OpenAICompatibleRerankResponse).results
  if (!Array.isArray(results)) {
    throw new Error('Rerank response must contain a results array')
  }

  return results.map((result) => {
    if (typeof result !== 'object' || result === null) {
      throw new Error('Rerank response results must be objects')
    }

    if (typeof result.index !== 'number' || typeof result.relevance_score !== 'number') {
      throw new Error('Rerank response results must contain numeric index and relevance_score')
    }

    if (!Number.isInteger(result.index) || result.index < 0 || result.index >= documentCount) {
      throw new Error('Rerank response results must reference a valid document index')
    }

    return { index: result.index, relevanceScore: result.relevance_score }
  })
}

export function createOpenAICompatibleRerankingModel(
  modelId: string,
  settings: OpenAICompatibleRerankingModelSettings
): RerankingModelV3 {
  const baseURL = withoutTrailingSlash(settings.baseURL)
  if (!baseURL) {
    throw new Error('OpenAI-compatible reranking model requires baseURL')
  }

View on GitHub (pinned to 726446b54c)

Solutions

  1. Check host network egress to the image URLs' hostnames and TLS/proxy settings in the main process.
  2. Verify free disk space and write permissions on the userData/file_entry storage location.
  3. If URLs expire, download sooner (reduce work between poll completion and download) or request longer-lived URLs via providerOptions if the vendor supports it.
  4. Retry the job once after a transient CDN/network blip — a single retry is cheap since the failure was post-generation (note: job retry is capped at 1 attempt by defaultRetryPolicy, so re-enqueue from the UI).
  5. Inspect the warn logs for individual download errors to see whether it was a network failure, a parse failure, or a persistence failure.

Example fix

// before: downloads happen with no per-URL diagnostics on total failure
for (const url of urls) {
  const downloaded = await downloadImageAsBase64(url, signal)
  files.push(await fileManager.createInternalEntry({ source: 'base64', data: toDataUrl(downloaded), cleanupPolicy }))
}
// after: capture per-URL failure reasons so the thrown error is diagnosable
const failures: string[] = []
for (const url of urls) {
  try {
    const downloaded = await downloadImageAsBase64(url, signal)
    files.push(await fileManager.createInternalEntry({ source: 'base64', data: toDataUrl(downloaded), cleanupPolicy }))
  } catch (e) { failures.push(`${url}: ${e instanceof Error ? e.message : String(e)}`) }
}
if (files.length === 0) throw new Error(`Image generation produced ${urls.length} URL(s) but all downloads failed [${failures.join('; ')}]`)
Defensive patterns

Strategy: retry

Validate before calling

// Best-effort preflight that the host can reach the vendor CDN host
// before paying for generation (cheap HEAD/GET to the image host root).
async function canReachCdn(host: string): Promise<boolean> {
  try { await fetch(`https://${host}/`, { method: 'HEAD' }); return true }
  catch { return false }
}

Try / catch

try {
  await generateImageViaJob(payload)
} catch (e) {
  if (e instanceof Error && /all downloads failed/.test(e.message)) {
    // post-generation failure: a single re-enqueue is cheap and often recovers a transient CDN blip
    await retryGenerateImageViaJob(payload)
  } else throw e
}

Prevention

When it happens

Trigger: All returned image URLs are expired/revoked by the time download runs (short-lived signed URLs); the host cannot reach the vendor's CDN/edge due to firewall or DNS; disk full or the file_entry store is unwritable so every createInternalEntry rejects; a proxy intercepts and blocks the image hosts; the media_type/data parsing throws for every entry.

Common situations: Network egress restrictions in a containerized/sandboxed main process blocking the image CDN; a long poll delay causing signed URLs to expire before download; disk pressure on the userData volume; corporate proxy certificate rejection on the image host; vendor CDN regional outage.

Related errors


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