flipped-aurora/gin-vue-admin · error
缺少分片 %d: %w
Error message
缺少分片 %d: %w
What it means
MergeChunks reassembles uploaded chunk files (<i>.part) under ChunkDir(uploadID) into the final file while computing MD5. If any expected chunk file cannot be opened, it aborts with "缺少分片 %d: %w". This guards against incomplete uploads being merged into corrupt files.
Source
Thrown at server/utils/upload/chunk.go:59
}
// MergeChunks 按 0..total-1 顺序流式合并到 dstPath,返回成品 md5
func MergeChunks(uploadID uint, total int, dstPath string) (string, error) {
if err := os.MkdirAll(filepath.Dir(dstPath), os.ModePerm); err != nil {
return "", err
}
out, err := os.Create(dstPath)
if err != nil {
return "", err
}
defer out.Close()
h := md5.New()
w := io.MultiWriter(out, h)
for i := 0; i < total; i++ {
p := filepath.Join(ChunkDir(uploadID), fmt.Sprintf("%d.part", i))
in, err := os.Open(p)
if err != nil {
return "", fmt.Errorf("缺少分片 %d: %w", i, err)
}
if _, err := io.Copy(w, in); err != nil {
in.Close()
return "", err
}
in.Close()
}
return hex.EncodeToString(h.Sum(nil)), nil
}
// RemoveUploadDir 删除某次上传的暂存目录
func RemoveUploadDir(uploadID uint) error {
return os.RemoveAll(ChunkDir(uploadID))
}
// ReceivedIndexes 扫描暂存目录已存在的分片索引(机会式恢复用,可选)
func ReceivedIndexes(uploadID uint) []int {
entries, err := os.ReadDir(ChunkDir(uploadID))View on GitHub (pinned to 3136500ef3)
Solutions
- Re-upload the missing chunk(s) reported by the error index before calling MergeChunks.
- Verify the client sends every chunk index 0..total-1 and confirm chunk completeness server-side before merging.
- Check ChunkDir(uploadID) for the expected .part files (ls the directory) to find which are missing.
- If chunks were cleaned up, restart the whole chunked upload with a new uploadID.
Example fix
// before
merged, _ := MergeChunks(id, 5, dest) // chunk 3 never uploaded
// after
for i := 0; i < 5; i++ {
if _, err := os.Stat(filepath.Join(ChunkDir(id), fmt.Sprintf("%d.part", i))); err != nil {
uploadChunk(id, i, data[i]) // re-send missing chunk
}
}
merged, err := MergeChunks(id, 5, dest) Defensive patterns
Strategy: validation
Validate before calling
func chunksComplete(uploadID string, total int) error {
for i := 0; i < total; i++ {
p := filepath.Join(ChunkDir(uploadID), fmt.Sprintf("%d.part", i))
if _, err := os.Stat(p); err != nil {
return fmt.Errorf("chunk %d missing", i)
}
}
return nil
} Try / catch
if err := chunksComplete(id, total); err != nil {
return retryMissingChunks(id, err) // re-upload missing parts before merge
}
md5, err := upload.MergeChunks(id, total, dest)
if err != nil {
return fmt.Errorf("merge aborted: %w", err)
} Prevention
- Track uploaded chunk indexes server-side and expose a completeness check endpoint
- Have the client confirm all chunk ACKs before requesting merge
- Use 0-based chunk indexing consistently on both sides
- Persist chunk progress so failed uploads can resume
When it happens
Trigger: Calling MergeChunks(uploadID, total, ...) when one or more files ChunkDir(uploadID)/i.part for i in [0,total) do not exist (os.Open fails) — typically because an earlier chunk upload failed or was never sent.
Common situations: Client aborted mid-upload and the UI still requested merge; network drop caused chunk 3 of 10 to fail; chunk index numbering mismatch (client sends 1-based, server expects 0-based); cleanup job removed partial chunk dirs.
Related errors
- function file.Open() failed, err:
- 构造 FileHeader 失败
- 上传不在可合并状态(可能已在合并或已完成)
- 整文件校验失败
- invalid plugin archive name
AI-assisted analysis of flipped-aurora/gin-vue-admin@3136500ef3 (2026-08-31).
Data as JSON: /api/errors/132492c30423afbf.
Report an issue: GitHub.