{"record":{"id":"8b1fb8e44e723d69","repo":"AlistGo/alist","slug":"doubao-new-finish-upload-missing-upload-id","errorCode":null,"errorMessage":"[doubao_new] finish upload missing upload_id","messagePattern":"\\[doubao_new\\] finish upload missing upload_id","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/doubao_new/util.go","lineNumber":876,"sourceCode":"\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/v3/block/?\" + values.Encode()\n\n\tres, err := req.Execute(http.MethodPost, urlStr)\n\tif err != nil {\n\t\treturn err\n\t}\n\tbody := res.Body()\n\tif err := decodeBaseResp(body, res); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (d *DoubaoNew) finishUpload(ctx context.Context, uploadID string, numBlocks int, mountPoint string) (UploadFinishData, error) {\n\tif uploadID == \"\" {\n\t\treturn UploadFinishData{}, fmt.Errorf(\"[doubao_new] finish upload missing upload_id\")\n\t}\n\tif numBlocks <= 0 {\n\t\treturn UploadFinishData{}, fmt.Errorf(\"[doubao_new] finish upload invalid num_blocks\")\n\t}\n\tif mountPoint == \"\" {\n\t\tmountPoint = \"explorer\"\n\t}\n\tvar resp UploadFinishResp\n\t_, err := d.request(ctx, \"/space/api/box/upload/finish/\", http.MethodPost, func(req *resty.Request) {\n\t\tvalues := url.Values{}\n\t\tvalues.Set(\"shouldBypassScsDialog\", \"true\")\n\t\tvalues.Set(\"doubao_storage\", \"imagex_other\")\n\t\tvalues.Set(\"doubao_app_id\", \"497858\")\n\t\treq.SetQueryParamsFromValues(values)\n\t\treq.SetHeader(\"Content-Type\", \"application/json\")\n\t\treq.SetHeader(\"x-command\", \"space.api.box.upload.finish\")\n\t\treq.SetHeader(\"rpc-persist-doubao-pan\", \"true\")\n\t\treq.SetHeader(\"cache-control\", \"no-cache\")","sourceCodeStart":858,"sourceCodeEnd":894,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/doubao_new/util.go#L858-L894","documentation":"finishUpload finalizes a completed upload session via POST /space/api/box/upload/finish/ and first validates that uploadID is non-empty. An empty identifier means finalize was attempted without a successful prepare, so the server would have no session to finish.","triggerScenarios":"Calling finishUpload after prepare failed or returned an empty UploadID; state lost between prepare and finish (variable shadowing, early error swallowed); direct invocation with \"\".","commonSituations":"Error-handling paths that continue to finish even when prepare errored; API schema change emptying the UploadID field; refactors that rename the variable and pass the wrong one.","solutions":["Check the prepare result immediately after it returns and abort the upload if UploadID is empty.","Ensure error paths short-circuit (return on first error) so finish is never reached with partial state.","Log the full prepare response once to confirm which field carries the upload_id."],"exampleFix":"// before\nprep, _ := d.prepareUpload(ctx, ...)\ndata, err := d.finishUpload(ctx, prep.UploadID, n, \"explorer\")\n\n// after\nprep, err := d.prepareUpload(ctx, ...)\nif err != nil { return UploadFinishData{}, err }\nif prep.UploadID == \"\" { return UploadFinishData{}, fmt.Errorf(\"[doubao_new] prepare returned empty upload_id\") }\ndata, err := d.finishUpload(ctx, prep.UploadID, n, \"explorer\")","handlingStrategy":"validation","validationCode":"prep, err := d.prepareUpload(ctx, ...)\nif err != nil { return err }\nif prep.UploadID == \"\" { return fmt.Errorf(\"prepare returned empty upload_id\") }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Short-circuit on the first error in the upload chain so finish is never reached with partial state.","Validate prepare output before block upload begins."],"tags":["doubao","upload","validation"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}