chenhg5/cc-connect · error
resource chunk offset=%d: %w
Error message
resource chunk offset=%d: %w
What it means
This error wraps a failure that occurred while downloading one non-first chunk of a Feishu message resource (file/image) via an HTTP Range request in resourceFetchRemainingChunks. The library chunks large downloads after a size probe and fetches each chunk with resourceRangeChunk; when any chunk fetch fails, it wraps the underlying error with the chunk's byte offset so callers can tell where the assembly broke. The offset is the start byte of the chunk that failed.
Source
Thrown at platform/feishu/resource_download.go:204
// byte, concatenates them with `first`, and verifies the total size matches
// what the probe advertised.
func (p *Platform) resourceFetchRemainingChunks(ctx context.Context, token, messageID, fileKey, resType string, total int64, first []byte) ([]byte, error) {
buf := bytes.NewBuffer(make([]byte, 0, total))
buf.Write(first)
chunkSize := p.resourceChunkSize
if chunkSize > resourceRangeMaxRangeHeaderBytes {
chunkSize = resourceRangeMaxRangeHeaderBytes
}
chunks := 1 // count the first byte we already have
for offset := int64(1); offset < total; offset += chunkSize {
end := offset + chunkSize - 1
if end >= total {
end = total - 1
}
n, err := p.resourceRangeChunk(ctx, token, messageID, fileKey, resType, offset, end, total)
if err != nil {
return nil, fmt.Errorf("resource chunk offset=%d: %w", offset, err)
}
buf.Write(n)
chunks++
if err := ctx.Err(); err != nil {
return nil, err
}
}
if int64(buf.Len()) != total {
return nil, fmt.Errorf("resource size mismatch: assembled=%d expected=%d", buf.Len(), total)
}
slog.Info(p.tag()+": resource chunked download complete",
"file_key", fileKey, "type", resType, "total", total, "chunks", chunks,
"chunk_size", chunkSize)
return buf.Bytes(), nil
}
// parseContentRangeTotal extracts the "total" field from a Content-RangeView on GitHub (pinned to 4000b2338a)
Solutions
- Retry the download; resourceRangeChunk already retries transient errors up to maxTransientRetries, so persistent failures usually mean network or auth issues — refresh the tenant_access_token and retry
- Check that the token passed to resourceDownloadStream is a valid, unexpired tenant_access_token with im:resource read permission
- Verify network/proxy allows HTTP Range (partial content) requests to open.feishu.cn
- Inspect the wrapped cause (%w) in logs — the underlying resourceRangeChunk error (status code, network error) names the real problem
- If the file is small enough, rely on resourceSingleGet (used when the size probe fails) which avoids chunking entirely
Example fix
// before: single call, no token refresh on long downloads
data, err := p.resourceDownloadStream(ctx, staleToken, msgID, fileKey, resType)
// after: obtain a fresh token before starting a chunked download
token, err := p.freshTenantToken(ctx)
if err != nil { return nil, err }
data, err := p.resourceDownloadStream(ctx, token, msgID, fileKey, resType) Defensive patterns
Strategy: retry
Validate before calling
// before download
if token == "" { return fmt.Errorf("missing tenant_access_token") }
if msgID == "" || fileKey == "" { return fmt.Errorf("empty message_id/file_key") } Try / catch
data, err := p.resourceDownloadStream(ctx, token, msgID, fileKey, resType)
if err != nil {
if strings.Contains(err.Error(), "resource chunk offset=") {
// refresh token, wait briefly, retry once
return retryDownload(ctx, msgID, fileKey, resType)
}
return err
} Prevention
- Always fetch a fresh tenant_access_token before long downloads
- Ensure network path supports HTTP Range requests (no Range-stripping proxies)
- Monitor Feishu API status for incidents before large transfers
When it happens
Trigger: Calling resourceDownloadStream for a resource whose probed total size exceeds the chunk size, causing resourceFetchRemainingChunks to issue Range GETs; a chunk's HTTP request fails (network error, non-206 status, server rejecting Range, auth token expiring mid-download), so resourceRangeChunk returns an error.
Common situations: Flaky network or proxy dropping long multi-chunk downloads; Feishu API returning 4xx/5xx on Range requests because the tenant_access_token expired between chunks; server ignoring the Range header and returning 200 instead of 206; corporate firewall blocking partial-content requests.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/ed2eb9713aec70b2.
Report an issue: GitHub.