weaviate/weaviate · error

failed to parse reranker response (status %d): %w

Error message

failed to parse reranker response (status %d): %w

What it means

Returned by the VoyageAI reranker client when the JSON body of a response from the VoyageAI rerank endpoint cannot be unmarshaled into the expected RankResponse (containing a 'data' array). The original unmarshal error is wrapped so the root cause (type mismatch, unexpected JSON) is preserved. The status code is included, and unlike the transformers client, this parse only runs after non-2xx statuses were already handled.

Source

Thrown at modules/reranker-voyageai/clients/ranker.go:153

	if err != nil {
		return nil, errors.Wrap(err, "read response body")
	}

	if res.StatusCode != 200 {
		var apiError voyageAiApiError
		err = json.Unmarshal(bodyBytes, &apiError)
		if err != nil {
			return nil, errors.Wrap(err, "unmarshal error from response body")
		}
		if apiError.Message != "" {
			return nil, errors.Errorf("connection to VoyageAI API failed with status %d: %s", res.StatusCode, apiError.Message)
		}
		return nil, errors.Errorf("connection to VoyageAI API failed with status %d", res.StatusCode)
	}

	var rankResponse RankResponse
	if err := json.Unmarshal(bodyBytes, &rankResponse); err != nil {
		return nil, fmt.Errorf("failed to parse reranker response (status %d): %w", res.StatusCode, err)
	}
	return c.toDocumentScores(documents, rankResponse.Data), nil
}

func (c *client) chunkDocuments(documents []string, chunkSize int) [][]string {
	var requests [][]string
	for i := 0; i < len(documents); i += chunkSize {
		end := i + chunkSize

		if end > len(documents) {
			end = len(documents)
		}

		requests = append(requests, documents[i:end])
	}

	return requests
}

View on GitHub (pinned to 75aa4b6d11)

Solutions

  1. Log/inspect the raw response body to see what VoyageAI actually returned
  2. Pin/verify the voyageai rerank model name matches one with the documented response shape (voyage-rerank-*)
  3. Update the client's RankResponse struct if VoyageAI changed their schema
  4. Check for proxies or network issues that could truncate the response body
Defensive patterns

Strategy: try-catch

Validate before calling

// verify API key and model are set before calls
if apiKey == "" || !strings.HasPrefix(model, "rerank-") {
	return errors.New("voyageai reranker requires API key and a valid rerank model")
}

Type guard

func isVoyageParseFailure(err error) bool {
	return err != nil && strings.Contains(err.Error(), "failed to parse reranker response")
}

Try / catch

scores, err := client.PerformRank(ctx, query, docs)
if err != nil {
	if strings.Contains(err.Error(), "failed to parse reranker response") {
		// dump raw body for schema comparison, then report
	}
	return err
}

Prevention

When it happens

Trigger: VoyageAI returns a 200 response whose body does not match RankResponse — e.g. schema change on VoyageAI's side, a truncated/chunked body corrupted during reading, or an unexpected JSON envelope.

Common situations: VoyageAI API response format changes; document chunks producing malformed responses; network intermediary altering the body; using a rerank model whose response shape differs from the client's expectation.

Understand the failure class

Related errors


AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04). Data as JSON: /api/errors/bcfc147dfbd761fd. Report an issue: GitHub.