chenhg5/cc-connect · error

resource too large: body exceeds cap %d

Error message

resource too large: body exceeds cap %d

What it means

Thrown when the server ignored the Range header and sent the whole file in one 200 response, and the body length exceeds resourceMaxBytes even after the LimitReader cap. Functionally identical to the body>cap guard in resourceDownloadStream, but raised inside resourceFetchFirstChunk on the 200 path; the difference is only where the size was observed.

Source

Thrown at platform/feishu/resource_download.go:176

		if !ok {
			return nil, 0, fmt.Errorf("first-chunk: 206 without parseable Content-Range %q", cr)
		}
		body, err := io.ReadAll(io.LimitReader(resp.Body, 1))
		if err != nil {
			return nil, 0, fmt.Errorf("read first-chunk body: %w", err)
		}
		return body, total, nil

	case http.StatusOK:
		// Server ignored Range and sent the full body. We deliberately
		// honour it and skip the chunked loop — this matches pre-#1741
		// behaviour for files small enough that Feishu doesn't truncate.
		body, err := io.ReadAll(io.LimitReader(resp.Body, p.resourceMaxBytes+1))
		if err != nil {
			return nil, 0, fmt.Errorf("read full body: %w", err)
		}
		if int64(len(body)) > p.resourceMaxBytes {
			return nil, 0, fmt.Errorf("resource too large: body exceeds cap %d", p.resourceMaxBytes)
		}
		return body, 0, nil

	default:
		return nil, 0, fmt.Errorf("first-chunk: unexpected status %d", resp.StatusCode)
	}
}

// resourceFetchRemainingChunks loops Range GETs starting after the first
// 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

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Raise resource_max_bytes in config.toml to the maximum file size users are expected to send
  2. Fix or remove the intermediary stripping the Range header so large files can be fetched chunk-wise
  3. Handle the error at the bot layer by replying to the user that the file is too large to fetch

Example fix

// before (config.toml)
# resource_max_bytes default (small)
// after
[platform.feishu]
resource_max_bytes = 209715200  # 200 MiB
Defensive patterns

Strategy: validation

Validate before calling

if meta.Size > maxResourceBytes { reply("file too large to fetch"); return }

Type guard

null

Try / catch

if err != nil && strings.Contains(err.Error(), "body exceeds cap") {
    replyToUser("This file is larger than my download limit (" + human(maxResourceBytes) + ").")
}

Prevention

When it happens

Trigger: Feishu (or an intermediary) responds 200 with the full resource, io.ReadAll reads resourceMaxBytes+1 bytes, len(body) > resourceMaxBytes. Fires before the fallback logic in resourceDownloadStream can even see the probe result.

Common situations: User sends a very large file (e.g. 50+ MB) while resource_max_bytes is small; proxy stripping the Range header so the entire file always streams to the bot.

Understand the failure class

Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.

Related errors


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