{"record":{"id":"72f4aa062482cce6","repo":"AlistGo/alist","slug":"doubao-new-invalid-block-size-from-needed-list","errorCode":null,"errorMessage":"[doubao_new] invalid block size from needed list: seq=%d size=%d","messagePattern":"\\[doubao_new\\] invalid block size from needed list: seq=(.+?) size=(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/doubao_new/driver.go","lineNumber":347,"sourceCode":"\t\t\tgroupSeqs = groupSeqs[:0]\n\t\t\tgroupChecksums = groupChecksums[:0]\n\t\t\tgroupSizes = groupSizes[:0]\n\t\t\tgroupRealSize = 0\n\t\t\tgroupExpectSum = 0\n\t\t\tgroupBuf.Reset()\n\t\t\tif up != nil {\n\t\t\t\tpercent := float64(uploadedBytes) / float64(totalSize) * 100\n\t\t\t\tup(percent)\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\n\t\tfor _, item := range needed.NeededUploadBlocks {\n\t\t\tif _, ok := blockMeta[item.Seq]; !ok {\n\t\t\t\treturn nil, fmt.Errorf(\"[doubao_new] missing block meta for seq %d\", item.Seq)\n\t\t\t}\n\t\t\tif item.Size <= 0 {\n\t\t\t\treturn nil, fmt.Errorf(\"[doubao_new] invalid block size from needed list: seq=%d size=%d\", item.Seq, item.Size)\n\t\t\t}\n\t\t\toffset := int64(item.Seq) * blockSize\n\t\t\tbuf := make([]byte, int(item.Size))\n\t\t\tn, err := tmpFile.ReadAt(buf, offset)\n\t\t\tif err != nil && err != io.EOF && err != io.ErrUnexpectedEOF {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif n != len(buf) {\n\t\t\t\treturn nil, fmt.Errorf(\"[doubao_new] short read: seq=%d want=%d got=%d\", item.Seq, len(buf), n)\n\t\t\t}\n\t\t\tbuf = buf[:n]\n\t\t\trealAdler := adler32String(buf)\n\t\t\tif realAdler != item.Checksum {\n\t\t\t\treturn nil, fmt.Errorf(\"[doubao_new] block checksum mismatch: seq=%d offset=%d adler32=%s step2=%s\", item.Seq, offset, realAdler, item.Checksum)\n\t\t\t}\n\t\t\tpayloadStart := groupBuf.Len()\n\t\t\tgroupBuf.Write(buf)\n\t\t\tpayloadEnd := groupBuf.Len()","sourceCodeStart":329,"sourceCodeEnd":365,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/doubao_new/driver.go#L329-L365","documentation":"Doubao_new validation of server data: an entry in NeededUploadBlocks carries Size <= 0, which is impossible to read or checksum. The client rejects it before attempting any I/O because buf := make([]byte, item.Size) would panic or misbehave.","triggerScenarios":"The needed-blocks endpoint returns a zero/negative size for a seq — server-side data anomaly, response shape change where Size unmarshals from the wrong field (so stays 0), or the seq refers to a block the server already has and the entry is malformed.","commonSituations":"Doubao web API contract change renaming size fields (Size vs BlockSize vs size), partial JSON so numbers stay zero, or server bug. Almost always paired with a broader upload failure for all files, not one specific file.","solutions":["If ALL uploads fail this way, suspect an API field rename — update/rebuild the doubao_new driver","Retry once to rule out a one-off malformed response","Capture the raw needed-blocks JSON (add temporary logging) and compare field names against the driver's structs","Report upstream with the raw response body","Re-login to get a fresh session; some malformed responses correlate with expired auth"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"for _, item := range needed.NeededUploadBlocks {\n    if item.Size <= 0 {\n        return fmt.Errorf(\"server returned invalid block size for seq %d; aborting before I/O\", item.Seq)\n    }\n}","typeGuard":"func validBlockItem(item NeededBlock) bool {\n    return item.Seq >= 0 && item.Size > 0 && item.Checksum != \"\"\n}","tryCatchPattern":"// treat as API contract break: fail fast with the raw entry for diagnostics\nif !validBlockItem(item) {\n    log.Printf(\"[doubao_new] malformed needed entry: %+v\", item)\n    return nil, fmt.Errorf(\"[doubao_new] invalid block size from needed list: seq=%d size=%d\", item.Seq, item.Size)\n}","preventionTips":["Validate all server-supplied sizes before allocation (the driver does — keep it)","If it fires for every file, diff raw JSON against driver structs; field renames are the usual cause","Pin driver versions that match the current Doubao web API"],"tags":["doubao-new","upload","validation","api-contract","go"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}