{"record":{"id":"883dbd6ed309067a","repo":"AlistGo/alist","slug":"doubao-new-v3-fallback-invalid-size-seq-d-size","errorCode":null,"errorMessage":"[doubao_new] v3 fallback invalid size: seq=%d size=%d","messagePattern":"\\[doubao_new\\] v3 fallback invalid size: seq=(.+?) size=(.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/doubao_new/util.go","lineNumber":790,"sourceCode":"\tbody := res.Body()\n\tvar resp UploadMergeResp\n\tif err := json.Unmarshal(body, &resp); err != nil {\n\t\tmsg := fmt.Sprintf(\"[doubao_new] decode response failed (status: %s, content-type: %s, body: %s): %v\",\n\t\t\tres.Status(),\n\t\t\tres.Header().Get(\"Content-Type\"),\n\t\t\tstring(body),\n\t\t\terr,\n\t\t)\n\t\treturn UploadMergeData{}, fmt.Errorf(msg)\n\t}\n\tif resp.Code != 0 {\n\t\tif res != nil && res.StatusCode() == http.StatusBadRequest && resp.Code == 2 {\n\t\t\tsuccess := make([]int, 0, len(seqList))\n\t\t\toffset := 0\n\t\t\tfor i, seq := range seqList {\n\t\t\t\tsize := sizeList[i]\n\t\t\t\tif size <= 0 {\n\t\t\t\t\treturn UploadMergeData{SuccessSeqList: success}, fmt.Errorf(\"[doubao_new] v3 fallback invalid size: seq=%d size=%d\", seq, size)\n\t\t\t\t}\n\t\t\t\tif offset+int(size) > len(data) {\n\t\t\t\t\treturn 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))\n\t\t\t\t}\n\t\t\t\tpayload := data[offset : offset+int(size)]\n\t\t\t\tblock := UploadBlockNeed{\n\t\t\t\t\tSeq:      seq,\n\t\t\t\t\tSize:     size,\n\t\t\t\t\tChecksum: checksumList[i],\n\t\t\t\t}\n\t\t\t\tif err := d.uploadBlockV3(ctx, uploadID, block, payload); err != nil {\n\t\t\t\t\treturn UploadMergeData{SuccessSeqList: success}, err\n\t\t\t\t}\n\t\t\t\tsuccess = append(success, seq)\n\t\t\t\toffset += int(size)\n\t\t\t}\n\t\t\treturn UploadMergeData{SuccessSeqList: success}, nil\n\t\t}","sourceCodeStart":772,"sourceCodeEnd":808,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/doubao_new/util.go#L772-L808","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Re-run the whole upload (fresh prepare + re-read the file) instead of trusting the current block metadata.","Filter zero-size blocks out of groupSeqs/groupSizes before calling mergeUploadBlocks so the fallback never sees size 0.","Verify the spooled file size equals the announced object size before upload begins."],"exampleFix":"// before\nblocks = append(blocks, block) // even when n == 0\n\n// after\nif n == 0 {\n    continue // never register an empty block\n}\nblocks = append(blocks, block)","handlingStrategy":"validation","validationCode":"for i, s := range sizeList {\n    if s <= 0 {\n        return fmt.Errorf(\"invalid size %d at index %d (seq %d); restart upload\", s, i, seqList[i])\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never register zero-size blocks when hashing the file.","On any fallback inconsistency, restart the upload from prepare instead of salvaging."],"tags":["doubao","upload","fallback","validation"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}