{"record":{"id":"a5f573a2be2cd77d","repo":"AlistGo/alist","slug":"doubao-new-merge-blocks-missing-x-command-header","errorCode":null,"errorMessage":"[doubao_new] merge blocks missing x-command header","messagePattern":"\\[doubao_new\\] merge blocks missing x-command header","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/doubao_new/util.go","lineNumber":751,"sourceCode":"\treqID := \"\"\n\tif buf := make([]byte, 16); true {\n\t\tif _, err := rand.Read(buf); err == nil {\n\t\t\treqID = hex.EncodeToString(buf)\n\t\t}\n\t}\n\tif reqID != \"\" {\n\t\treq.SetHeader(\"x-request-id\", reqID)\n\t}\n\tif auth := d.resolveAuthorization(); auth != \"\" {\n\t\treq.SetHeader(\"authorization\", auth)\n\t}\n\tif dpop := d.resolveDpop(); dpop != \"\" {\n\t\treq.SetHeader(\"dpop\", dpop)\n\t}\n\treq.Header.Del(\"Cookie\")\n\treq.Header.Del(\"cookie\")\n\tif req.Header.Get(\"x-command\") == \"\" {\n\t\treturn UploadMergeData{}, fmt.Errorf(\"[doubao_new] merge blocks missing x-command header\")\n\t}\n\treq.SetBody(data)\n\n\tvalues := url.Values{}\n\tvalues.Set(\"shouldBypassScsDialog\", \"true\")\n\tvalues.Set(\"upload_id\", uploadID)\n\tvalues.Set(\"mount_point\", \"explorer\")\n\tvalues.Set(\"doubao_storage\", \"imagex_other\")\n\tvalues.Set(\"doubao_app_id\", \"497858\")\n\turlStr := \"https://internal-api-drive-stream.feishu.cn/space/api/box/stream/upload/merge_block/?\" + values.Encode()\n\n\tres, err := req.Execute(http.MethodPost, urlStr)\n\tif err != nil {\n\t\treturn UploadMergeData{}, err\n\t}\n\tif v := res.Header().Get(\"X-Tt-Logid\"); v != \"\" {\n\t\td.TtLogid = v\n\t} else if v := res.Header().Get(\"x-tt-logid\"); v != \"\" {","sourceCodeStart":733,"sourceCodeEnd":769,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/doubao_new/util.go#L733-L769","documentation":"A defensive invariant check in mergeUploadBlocks: after all headers are applied it verifies that the x-command header (the RPC route name, here \"space.api.box.stream.upload.merge_block\", set unconditionally at util.go:731) is present before executing the request. In the current code this can only fire if that SetHeader line is removed or a refactor moves it after the guard.","triggerScenarios":"Custom forks or future refactors that delete/conditionalize req.SetHeader(\"x-command\", ...) (util.go:731); middleware or a header-sanitizing proxy stripping the header before the check; copy-pasting the request-building block into a new function without the x-command line.","commonSituations":"Maintainers refactoring the header setup into a shared helper and dropping one header; adding conditional header logic that accidentally skips x-command; not hit by end users on stock code.","solutions":["Restore the unconditional header: req.SetHeader(\"x-command\", \"space.api.box.stream.upload.merge_block\") before the guard.","If headers were extracted to a helper, pass the command name as a parameter and assert it is non-empty in the helper.","Treat this error as a code bug (assertion), not a runtime condition: do not retry the upload."],"exampleFix":"// before\nreq.SetHeader(\"accept\", \"application/json, text/plain, */*\")\n// ... x-command line missing after refactor\n\n// after\nreq.SetHeader(\"x-command\", \"space.api.box.stream.upload.merge_block\")\nif req.Header.Get(\"x-command\") == \"\" {\n    return UploadMergeData{}, fmt.Errorf(\"[doubao_new] merge blocks missing x-command header\")\n}","handlingStrategy":"validation","validationCode":"// assertion-style: keep the header set adjacent to the guard\nreq.SetHeader(\"x-command\", \"space.api.box.stream.upload.merge_block\")\nif req.Header.Get(\"x-command\") == \"\" { /* invariant violated: code bug */ }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["When refactoring header setup, keep the guard next to the SetHeader call.","Treat this error as an assertion failure: fix code, never retry."],"tags":["doubao","upload","invariant","headers"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}