AlistGo/alist · error

[doubao_new] v3 fallback payload out of range: seq=%d offset

Error message

[doubao_new] v3 fallback payload out of range: seq=%d offset=%d size=%d total=%d

What it means

Second guard in the v3 fallback loop: the cumulative offset plus the block's size would slice past the end of data, meaning sum(sizeList) > len(data). The concatenated payloads no longer match the declared sizes, so re-upload cannot proceed.

Source

Thrown at drivers/doubao_new/util.go:793

		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
		}
		errMsg := resp.Msg
		if errMsg == "" {
			errMsg = resp.Message

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Restart the upload end-to-end with a fresh upload_id; partial state is inconsistent.
  2. Add a pre-check where data is assembled: fail if int64(len(data)) != sum(groupSizes) (the flushGroup check exists but only compares against groupExpectSum — make sure groupExpectSum is derived from the same sizeList).
  3. Ensure the source file is immutable for the duration of the upload (copy-on-write snapshot or lock).

Example fix

// before
payload := data[offset : offset+int(size)]

// after
total := int64(0)
for _, s := range sizeList { total += s }
if total != int64(len(data)) {
    return UploadMergeData{}, fmt.Errorf("[doubao_new] sizes/data mismatch: sum=%d len=%d", total, len(data))
}
Defensive patterns

Strategy: validation

Validate before calling

total := int64(0)
for _, s := range sizeList { total += s }
if total != int64(len(data)) {
    return fmt.Errorf("sizes/data mismatch: sum=%d len=%d", total, len(data))
}

Prevention

When it happens

Trigger: mergeUploadBlocks is invoked with sizeList that sums to more than the actual data buffer length — e.g., data was truncated after sizes were computed, sizes come from a different file version, or a caller passes mismatched parallel slices. Reached only after a 400/code-2 merge rejection triggers the fallback.

Common situations: File modified during upload (size changed between hashing and reading); tmpFile shorter than expected; bug in group accumulation where groupSizes retains entries from a previous group.

Related errors


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