Tencent/WeKnora · error

failed to read Zhipu response: %w

Error message

failed to read Zhipu response: %w

What it means

readZhipuResponseBody fails when io.ReadAll on the (rate-limited) response body errors — the connection dropped or the stream broke mid-read. The error is wrapped with %w so the underlying io error is preserved.

Source

Thrown at internal/infrastructure/web_search/zhipu.go:220

		return time.Time{}, false
	}
	for _, layout := range []string{
		time.RFC3339Nano,
		"2006-01-02 15:04:05",
		"2006-01-02 15:04",
		"2006-01-02",
	} {
		if parsed, err := time.Parse(layout, value); err == nil {
			return parsed, true
		}
	}
	return time.Time{}, false
}

func readZhipuResponseBody(reader io.Reader) ([]byte, error) {
	body, err := io.ReadAll(io.LimitReader(reader, maxZhipuResponseBytes+1))
	if err != nil {
		return nil, fmt.Errorf("failed to read Zhipu response: %w", err)
	}
	if len(body) > maxZhipuResponseBytes {
		return nil, fmt.Errorf("Zhipu response exceeds %d bytes", maxZhipuResponseBytes)
	}
	return body, nil
}

func zhipuHTTPError(statusCode int, body []byte) error {
	var response zhipuSearchResponse
	if err := json.Unmarshal(body, &response); err == nil && (response.Error.Code != "" || response.Error.Message != "") {
		return fmt.Errorf("Zhipu API returned status %d (%s): %s", statusCode, response.Error.Code, response.Error.Message)
	}
	detail := strings.TrimSpace(string(body))
	if len(detail) > 4096 {
		detail = detail[:4096]
	}
	if detail == "" {
		return fmt.Errorf("Zhipu API returned status %d", statusCode)

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Retry the request — mid-stream read failures are usually transient
  2. Increase client timeout if large responses are expected on slow links
  3. Disable aggressive keep-alive idle timeouts that kill in-flight connections
  4. Check intermediate proxies/load balancer idle timeout settings

Example fix

// before
body, err := readZhipuResponseBody(resp.Body)
if err != nil { return nil, err }
// after
body, err := readZhipuResponseBody(resp.Body)
if err != nil {
    if errors.Is(err, io.ErrUnexpectedEOF) { return retry(ctx, req) }
    return nil, err
}
Defensive patterns

Strategy: retry

Type guard

func isBodyReadError(err error) bool { return strings.Contains(err.Error(), "failed to read Zhipu response") }

Try / catch

results, err := provider.Search(ctx, q)
if err != nil && errors.Is(err, io.ErrUnexpectedEOF) {
    return retryWithBackoff(ctx, q) // mid-stream disconnect
}

Prevention

When it happens

Trigger: Calling Search() when the Zhipu server closes the connection before the body completes, or the client/context is cancelled during body read.

Common situations: Flaky mobile/VPN networks; server-side timeouts on slow responses; LBs terminating idle keep-alive connections mid-transfer.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/2228026c282b7be9. Report an issue: GitHub.