{"record":{"id":"cab188ff2eddcfd2","repo":"AlistGo/alist","slug":"invalid-hash-cab188","errorCode":null,"errorMessage":"invalid hash","messagePattern":"invalid hash","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/baidu_netdisk/driver.go","lineNumber":173,"sourceCode":"\t\t\t\"path\":    srcObj.GetPath(),\n\t\t\t\"dest\":    dstDir.GetPath(),\n\t\t\t\"newname\": srcObj.GetName(),\n\t\t},\n\t}\n\t_, err := d.manage(\"copy\", data)\n\treturn err\n}\n\nfunc (d *BaiduNetdisk) Remove(ctx context.Context, obj model.Obj) error {\n\tdata := []string{obj.GetPath()}\n\t_, err := d.manage(\"delete\", data)\n\treturn err\n}\n\nfunc (d *BaiduNetdisk) PutRapid(ctx context.Context, dstDir model.Obj, stream model.FileStreamer) (model.Obj, error) {\n\tcontentMd5 := stream.GetHash().GetHash(utils.MD5)\n\tif len(contentMd5) < utils.MD5.Width {\n\t\treturn nil, errors.New(\"invalid hash\")\n\t}\n\n\tstreamSize := stream.GetSize()\n\tpath := stdpath.Join(dstDir.GetPath(), stream.GetName())\n\tmtime := stream.ModTime().Unix()\n\tctime := stream.CreateTime().Unix()\n\tblockList, _ := utils.Json.MarshalToString([]string{contentMd5})\n\n\tvar newFile File\n\t_, err := d.create(path, streamSize, 0, \"\", blockList, &newFile, mtime, ctime)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\t// 修复时间，具体原因见 Put 方法注释的 **注意**\n\tnewFile.Ctime = stream.CreateTime().Unix()\n\tnewFile.Mtime = stream.ModTime().Unix()\n\treturn fileToObj(newFile), nil\n}","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/baidu_netdisk/driver.go#L155-L191","documentation":"Returned by PutRapid() in the Baidu Netdisk driver when the file stream's MD5 hash is missing or shorter than a full MD5 (32 hex chars). Rapid (instant) upload works only by presenting a complete content MD5, so a partial/absent hash aborts the operation.","triggerScenarios":"Calling PutRapid with a model.FileStreamer whose hash registry has no MD5 entry (e.g. the file was not hashed before upload) or only a prefix (hashing still in progress / truncated).","commonSituations":"Uploading through an API/webdav path that does not compute MD5 before put; local upload setting has hash detection disabled; copying a stream whose hash was consumed or never set.","solutions":["Enable MD5 hashing for the upload pipeline so the stream carries a full 32-char MD5 before PutRapid is attempted","If invoking PutRapid programmatically, wrap the stream and pre-compute the MD5 (read once or hash on the fly) before calling","Fall back to the normal chunked Put path when no MD5 is available instead of PutRapid"],"exampleFix":"// before\nobj, err := d.PutRapid(ctx, dstDir, stream) // stream has no MD5\n// after: compute hash first, or skip rapid path\nif h := stream.GetHash().GetHash(utils.MD5); len(h) < utils.MD5.Width {\n    return d.Put(ctx, dstDir, stream, up) // normal upload\n}","handlingStrategy":"validation","validationCode":"func canRapidUpload(s model.FileStreamer) bool {\n    return len(s.GetHash().GetHash(utils.MD5)) >= utils.MD5.Width\n}\nif !canRapidUpload(stream) { /* use normal Put */ }","typeGuard":"func hasFullMD5(s model.FileStreamer) bool {\\n    return len(s.GetHash().GetHash(utils.MD5)) >= utils.MD5.Width\\n}","tryCatchPattern":"if _, err := d.PutRapid(ctx, dst, stream); err != nil && strings.Contains(err.Error(), \"invalid hash\") { err = d.Put(ctx, dst, stream, up) }","preventionTips":["Compute MD5 before initiating transfers where rapid upload is desired","Enable hash computation in upload settings","Treat rapid upload as an optimization with a normal-upload fallback"],"tags":["baidu-netdisk","upload","md5","rapid-upload"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}