AlistGo/alist · error
[doubao_new] merge blocks invalid body len: got=%d expect=%d
Error message
[doubao_new] merge blocks invalid body len: got=%d expect=%d seqs=%v
What it means
Doubao_new driver (new web API) merge-group sanity check: the concatenated block buffer for a merge group does not have the byte length accumulated in groupExpectSum from the server-provided per-block sizes. The client refuses to send a merge request whose declared sizes wouldn't match its body.
Source
Thrown at drivers/doubao_new/driver.go:309
flushGroup := func() error {
if len(groupSeqs) == 0 {
return nil
}
data := groupBuf.Bytes()
expectLen := groupExpectSum
if len(data) > 0 {
headLen := 32
if len(data) < headLen {
headLen = len(data)
}
tailLen := 32
if len(data) < tailLen {
tailLen = len(data)
}
}
if int64(len(data)) != expectLen {
return fmt.Errorf("[doubao_new] merge blocks invalid body len: got=%d expect=%d seqs=%v", len(data), expectLen, groupSeqs)
}
mergeResp, err := d.mergeUploadBlocks(ctx, uploadPrep.UploadID, groupSeqs, groupChecksums, groupSizes, blockSize, data)
if err != nil {
return err
}
if len(mergeResp.SuccessSeqList) != len(groupSeqs) {
return fmt.Errorf("[doubao_new] merge blocks incomplete: %v", mergeResp.SuccessSeqList)
}
success := make(map[int]bool, len(mergeResp.SuccessSeqList))
for _, seq := range mergeResp.SuccessSeqList {
success[seq] = true
}
for _, seq := range groupSeqs {
if !success[seq] {
return fmt.Errorf("[doubao_new] merge blocks missing seq %d", seq)
}
}
View on GitHub (pinned to 843d9dc814)
Solutions
- Check disk space where the upload temp file is spooled; a truncated spool is the top cause
- Retry the upload — if server-side block metadata shifted between queries, a fresh pass re-reads consistent state
- Verify file size didn't change during upload (uploading a file being actively written produces length mismatches)
- If reproducible at the same seq every time, inspect the groupSizes vs actual ReadAt lengths in a debug run and report the driver bug
- Update the doubao_new driver — early versions had final-block sizing issues
Defensive patterns
Strategy: validation
Validate before calling
// before merging, assert spool consistency
if err := verifySpoolLength(tmpFile, totalSize); err != nil {
return fmt.Errorf("spool incomplete, aborting before merge: %w", err)
} Try / catch
if err := flushGroup(); err != nil {
if strings.Contains(err.Error(), "invalid body len") {
// length bookkeeping desynced: restart the upload pass
return d.uploadPass(ctx, ...)
}
return err
} Prevention
- Free ample temp disk space before large uploads
- Don't modify source files mid-upload
- Keep only one upload session per file
When it happens
Trigger: During incremental upload (dedup by block checksums), when the group of needed blocks read from the local temp file has total bytes != sum of item.Size values from the NeededUploadBlocks list — e.g. a short read silently accepted, block size list changed between queries, or blockMeta offsets inconsistent with blockSize.
Common situations: Temp file truncated (disk full while spooling), concurrent writers to the temp file, server returning updated block metadata after re-query, or a driver bug in blockSize arithmetic (seq * blockSize offsets) for the final partial block.
Related errors
- [doubao_new] missing block meta for seq %d
- [doubao_new] block checksum mismatch: seq=%d offset=%d adler
- [doubao_new] payload checksum mismatch: seq=%d start=%d end=
- upload part failed: crc32 mismatch, expected %s, got %s
- [doubao_new] merge blocks incomplete: %v
AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15).
Data as JSON: /api/errors/b5c13e422eed9ca4.
Report an issue: GitHub.