AlistGo/alist · error

[doubao_new] v3 fallback invalid size: seq=%d size=%d

Error message

[doubao_new] v3 fallback invalid size: seq=%d size=%d

What it means

When the merge endpoint answers HTTP 400 with code 2, the client falls back to re-uploading each block individually via uploadBlockV3, slicing data by cumulative offsets from sizeList. This error fires when a sizeList entry is <= 0, so the slice window is invalid before any payload is cut.

Source

Thrown at drivers/doubao_new/util.go:790

	body := res.Body()
	var resp UploadMergeResp
	if err := json.Unmarshal(body, &resp); err != nil {
		msg := fmt.Sprintf("[doubao_new] decode response failed (status: %s, content-type: %s, body: %s): %v",
			res.Status(),
			res.Header().Get("Content-Type"),
			string(body),
			err,
		)
		return UploadMergeData{}, fmt.Errorf(msg)
	}
	if resp.Code != 0 {
		if res != nil && res.StatusCode() == http.StatusBadRequest && resp.Code == 2 {
			success := make([]int, 0, len(seqList))
			offset := 0
			for i, seq := range seqList {
				size := sizeList[i]
				if size <= 0 {
					return UploadMergeData{SuccessSeqList: success}, fmt.Errorf("[doubao_new] v3 fallback invalid size: seq=%d size=%d", seq, size)
				}
				if offset+int(size) > len(data) {
					return UploadMergeData{SuccessSeqList: success}, fmt.Errorf("[doubao_new] v3 fallback payload out of range: seq=%d offset=%d size=%d total=%d", seq, offset, size, len(data))
				}
				payload := data[offset : offset+int(size)]
				block := UploadBlockNeed{
					Seq:      seq,
					Size:     size,
					Checksum: checksumList[i],
				}
				if err := d.uploadBlockV3(ctx, uploadID, block, payload); err != nil {
					return UploadMergeData{SuccessSeqList: success}, err
				}
				success = append(success, seq)
				offset += int(size)
			}
			return UploadMergeData{SuccessSeqList: success}, nil
		}

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Re-run the whole upload (fresh prepare + re-read the file) instead of trusting the current block metadata.
  2. Filter zero-size blocks out of groupSeqs/groupSizes before calling mergeUploadBlocks so the fallback never sees size 0.
  3. Verify the spooled file size equals the announced object size before upload begins.

Example fix

// before
blocks = append(blocks, block) // even when n == 0

// after
if n == 0 {
    continue // never register an empty block
}
blocks = append(blocks, block)
Defensive patterns

Strategy: validation

Validate before calling

for i, s := range sizeList {
    if s <= 0 {
        return fmt.Errorf("invalid size %d at index %d (seq %d); restart upload", s, i, seqList[i])
    }
}

Prevention

When it happens

Trigger: Server rejected the merged upload (400/code 2) AND the group's size list contains a zero or negative size — i.e., the caller built sizeList from blocks with Size 0 (empty reads) or corrupted block metadata. Only reachable after mergeUploadBlocks validation passed (sizes may be 0 and still pass, since only len mismatch is checked).

Common situations: Zero-byte blocks produced by a truncated temp file; block metadata built from a stale index; race where the file changed size between hashing and reading.

Related errors


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/883dbd6ed309067a. Report an issue: GitHub.