{"record":{"id":"e7419ff3a26e696c","repo":"AlistGo/alist","slug":"doubao-new-upload-v3-block-invalid-seq","errorCode":null,"errorMessage":"[doubao_new] upload v3 block invalid seq","messagePattern":"\\[doubao_new\\] upload v3 block invalid seq","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/doubao_new/util.go","lineNumber":824,"sourceCode":"\t\t\t}\n\t\t\treturn UploadMergeData{SuccessSeqList: success}, nil\n\t\t}\n\t\terrMsg := resp.Msg\n\t\tif errMsg == \"\" {\n\t\t\terrMsg = resp.Message\n\t\t}\n\t\treturn UploadMergeData{}, fmt.Errorf(\"[doubao_new] API error (code: %d): %s\", resp.Code, errMsg)\n\t}\n\n\treturn resp.Data, nil\n}\n\nfunc (d *DoubaoNew) uploadBlockV3(ctx context.Context, uploadID string, block UploadBlockNeed, data []byte) error {\n\tif uploadID == \"\" {\n\t\treturn fmt.Errorf(\"[doubao_new] upload v3 block missing upload_id\")\n\t}\n\tif block.Seq < 0 {\n\t\treturn fmt.Errorf(\"[doubao_new] upload v3 block invalid seq\")\n\t}\n\tif len(data) == 0 {\n\t\treturn fmt.Errorf(\"[doubao_new] upload v3 block empty data\")\n\t}\n\n\treq := base.RestyClient.R()\n\treq.SetContext(ctx)\n\treq.SetHeader(\"accept\", \"*/*\")\n\treq.SetHeader(\"origin\", \"https://www.doubao.com\")\n\treq.SetHeader(\"referer\", \"https://www.doubao.com/\")\n\treq.SetHeader(\"user-agent\", \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36\")\n\treq.SetHeader(\"rpc-persist-doubao-pan\", \"true\")\n\treq.SetHeader(\"x-block-seq\", strconv.Itoa(block.Seq))\n\treq.SetHeader(\"x-block-checksum\", block.Checksum)\n\tif auth := d.resolveAuthorization(); auth != \"\" {\n\t\treq.SetHeader(\"authorization\", auth)\n\t}\n\tif dpop := d.resolveDpop(); dpop != \"\" {","sourceCodeStart":806,"sourceCodeEnd":842,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/doubao_new/util.go#L806-L842","documentation":"uploadBlockV3 rejects a negative block.Seq, since the block sequence number is used for the x-block-seq header and ordering on the server. In stock code seqs are loop indices and cannot be negative; the guard protects custom callers and deserialized block metadata.","triggerScenarios":"Calling uploadBlockV3 with block metadata parsed from external input where Seq was absent (defaulting to -1 sentinel) or mis-parsed with a sign; corrupted block lists after a refactor.","commonSituations":"Custom integrations storing UploadBlockNeed as JSON and reloading with schema drift; sentinel values (-1) leaking into the upload path.","solutions":["Validate seq >= 0 when building the block list, not at upload time.","If loading block metadata from persistence, reject rows with negative seq at load time.","Re-run prepare to get a fresh, internally consistent block plan."],"exampleFix":"// before\nblock := UploadBlockNeed{Seq: seqFromFile}\n\n// after\nif seqFromFile < 0 {\n    return fmt.Errorf(\"invalid block seq %d\", seqFromFile)\n}\nblock := UploadBlockNeed{Seq: seqFromFile}","handlingStrategy":"validation","validationCode":"for _, b := range blocks {\n    if b.Seq < 0 { return fmt.Errorf(\"invalid block seq %d\", b.Seq) }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate seq at block-list build time.","Reject negative seqs when loading persisted block metadata."],"tags":["doubao","upload","validation"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}