chenhg5/cc-connect · error

build range request: %w

Error message

build range request: %w

What it means

resourceRangeChunk failed to construct its HTTP Range GET request via http.NewRequestWithContext and wraps the cause as "build range request". This mirrors the single-GET build failure but on the per-chunk path used for large downloads.

Source

Thrown at platform/feishu/resource_download.go:319

	var lastErr error
	delay := transientRetryInitial
	for attempt := 0; attempt <= maxTransientRetries; attempt++ {
		if attempt > 0 {
			select {
			case <-ctx.Done():
				return nil, ctx.Err()
			case <-time.After(delay):
			}
			delay *= 2
			if delay > transientRetryMaxDelay {
				delay = transientRetryMaxDelay
			}
		}

		req, err := http.NewRequestWithContext(ctx, http.MethodGet,
			p.resourceURL(messageID, fileKey, resType), nil)
		if err != nil {
			return nil, fmt.Errorf("build range request: %w", err)
		}
		req.Header.Set("Authorization", "Bearer "+token)
		req.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", start, end))

		resp, err := p.resourceDownloadHTTP.Do(req)
		if err != nil {
			if isTransientError(err) && attempt < maxTransientRetries {
				lastErr = err
				slog.Debug(p.tag()+": transient range chunk error; retrying",
					"attempt", attempt, "error", err, "start", start, "end", end)
				continue
			}
			return nil, fmt.Errorf("range request: %w", err)
		}

		if resp.StatusCode == http.StatusPartialContent {
			cr := resp.Header.Get("Content-Range")
			if cr != "" {

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Check the wrapped cause (%w) — url.Parse errors pinpoint the offending URL segment
  2. Validate messageID and fileKey (non-empty, URL-safe) before starting the chunked download
  3. Fix p.resourceURL / base URL configuration if it produces invalid URLs
  4. Since a per-chunk build failure repeats for every chunk, abort and fix inputs rather than retrying

Example fix

// before: use raw fileKey
req, err := http.NewRequestWithContext(ctx, http.MethodGet, p.resourceURL(messageID, fileKey, resType), nil)
// after: reject invalid keys up front
if fileKey == "" || strings.ContainsAny(fileKey, " \t\r\n%") {
    return nil, fmt.Errorf("feishu: invalid file_key %q", fileKey)
}
Defensive patterns

Strategy: validation

Validate before calling

func validRangeInputs(msgID, fileKey string) error {
    if msgID == "" { return fmt.Errorf("empty message_id") }
    if fileKey == "" { return fmt.Errorf("empty file_key") }
    return nil
}
// call before starting the chunked download
if err := validRangeInputs(msgID, fileKey); err != nil { return err }

Try / catch

data, err := p.resourceDownloadStream(ctx, token, msgID, fileKey, resType)
if err != nil {
    if strings.Contains(err.Error(), "build range request") {
        // deterministic failure: do not retry, fix inputs
        return nil, fmt.Errorf("bad resource identifiers: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: p.resourceURL(messageID, fileKey, resType) yields an unparseable URL when fetching a chunk — empty/invalid message_id or file_key, unescaped characters in the file key, or a malformed configured base URL — during a chunked download of a large resource.

Common situations: fileKey containing characters that break url.Parse (spaces, control chars, unencoded %-signs); message_id empty because the incoming message lacked it; base URL misconfigured behind a gateway.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/00693ebf4a7d0934. Report an issue: GitHub.