{"record":{"id":"caaf1161de0ffe03","repo":"Tencent/WeKnora","slug":"failed-to-copy-file-content-w","errorCode":null,"errorMessage":"failed to copy file content: %w","messagePattern":"failed to copy file content: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/application/service/file/local.go","lineNumber":206,"sourceCode":"\n\text := filepath.Ext(srcPath)\n\tfilename := fmt.Sprintf(\"%d%s\", time.Now().UnixNano(), ext)\n\tdstPath := filepath.Join(dir, filename)\n\n\tsrc, err := os.Open(srcResolved)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to open source file: %w\", err)\n\t}\n\tdefer src.Close()\n\n\tdst, err := os.Create(dstPath)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to create destination file: %w\", err)\n\t}\n\tdefer dst.Close()\n\n\tif _, err := io.Copy(dst, src); err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to copy file content: %w\", err)\n\t}\n\n\trelPath, _ := filepath.Rel(s.baseDir, dstPath)\n\tnewPath := localScheme + filepath.ToSlash(relPath)\n\tlogger.Infof(ctx, \"Copied local file %s to %s\", srcPath, newPath)\n\treturn newPath, nil\n}\n\n// SaveBytes saves bytes data to a file and returns the file path\n// temp parameter is ignored for local storage (no auto-expiration support)\n// fileName 仅允许安全文件名，禁止路径遍历（如 ../../）\nfunc (s *localFileService) SaveBytes(ctx context.Context, data []byte, tenantID uint64, fileName string, temp bool) (string, error) {\n\tlogger.Infof(ctx, \"Saving bytes data: fileName=%s, size=%d, tenantID=%d, temp=%v\", fileName, len(data), tenantID, temp)\n\n\tsafeName, err := secutils.SafeFileName(fileName)\n\tif err != nil {\n\t\tlogger.Errorf(ctx, \"Invalid fileName for SaveBytes: %v\", err)\n\t\treturn \"\", fmt.Errorf(\"invalid file name: %w\", err)","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/application/service/file/local.go#L188-L224","documentation":"io.Copy(dst, src) failed while streaming the source file's contents into the destination file. This is a mid-copy I/O failure: read errors from the source (I/O error, file truncated concurrently), write errors to the destination (disk full), or network-filesystem interruptions.","triggerScenarios":"Source file is modified/truncated while being read (concurrent writer); disk fills during the copy; NFS/EFS/S3-fuse mount drops mid-read; source file is on flaky removable/network storage.","commonSituations":"Large files copied while another process rewrites the source; volume runs out of space partway through a big copy; unstable network mounts (NFS stale handle, EFS timeout) in cloud deployments.","solutions":["Inspect the wrapped error: ENOSPC mid-copy → free space and retry; EIO/stale NFS handle → check mount health and remount.","Retry CopyFile after confirming source stability (no concurrent writers); consider copying to a temp file and atomically renaming on success.","Check for concurrent modification of the source and serialize writes to that file.","Monitor and expand volume capacity for large copies."],"exampleFix":"// before\nif _, err := io.Copy(dst, src); err != nil {\n    return \"\", fmt.Errorf(\"failed to copy file content: %w\", err)\n}\n// after\nif _, err := io.Copy(dst, src); err != nil {\n    dst.Close()\n    os.Remove(dstPath)\n    return \"\", fmt.Errorf(\"failed to copy file content: %w\", err)\n}\nif err := dst.Sync(); err != nil {\n    dst.Close()\n    os.Remove(dstPath)\n    return \"\", fmt.Errorf(\"failed to flush destination file: %w\", err)\n}","handlingStrategy":"retry","validationCode":"func checkCopyPrereqs(srcPath, dir string, minFreeBytes uint64) error {\n    if fi, err := os.Stat(srcPath); err != nil || !fi.Mode().IsRegular() {\n        return fmt.Errorf(\"source invalid\")\n    }\n    var st syscall.Statfs_t\n    if err := syscall.Statfs(dir, &st); err != nil {\n        return err\n    }\n    if uint64(st.Bavail)*uint64(st.Bsize) < minFreeBytes {\n        return fmt.Errorf(\"insufficient free space\")\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"var newPath string\nvar err error\nfor attempt := 0; attempt < 3; attempt++ {\n    newPath, err = svc.CopyFile(ctx, srcPath, tenantID, knowledgeID)\n    if err == nil {\n        break\n    }\n    if errors.Is(err, os.ErrPermission) || errors.Is(err, fs.ErrNotExist) {\n        break // non-transient: don't retry\n    }\n    time.Sleep(time.Duration(1<<attempt) * 100 * time.Millisecond)\n}\nif err != nil {\n    return fmt.Errorf(\"copy failed after retries: %w\", err)\n}","preventionTips":["Prevent concurrent writers from mutating the source while copying (locks or copy-on-write).","Keep generous headroom on the storage volume for large copies.","Prefer local-disk staging over flaky network mounts for intermediate copies.","Copy to a temp file and rename atomically so failed copies don't leave partial artifacts."],"tags":["filesystem","io","partial-write","disk-full"],"backgroundTag":"io-copy-failed","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}