{"record":{"id":"782d5ce817d8f56a","repo":"cloudreve/cloudreve","slug":"failed-to-copy-file-w","errorCode":null,"errorMessage":"failed to copy file: %w","messagePattern":"failed to copy file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"inventory/file.go","lineNumber":643,"sourceCode":"\t\tif file.PrimaryEntity > 0 {\n\t\t\tstm.SetPrimaryEntity(file.PrimaryEntity)\n\t\t}\n\n\t\tif file.Props != nil && dstMap[file.FileChildren][0].OwnerID == file.OwnerID {\n\t\t\tstm.SetProps(file.Props)\n\t\t}\n\n\t\treturn stm\n\t})\n\n\tmetadataStm := []*ent.MetadataCreate{}\n\tentityStm := []*ent.EntityUpdate{}\n\tnewDstMap := make(map[int][]*ent.File, len(files))\n\tsizeDiff := int64(0)\n\tfor index, stm := range copyFileStm {\n\t\tnewFile, err := stm.Save(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, nil, fmt.Errorf(\"failed to copy file: %w\", err)\n\t\t}\n\n\t\tfileMetadata, err := files[index].Edges.MetadataOrErr()\n\t\tif err != nil {\n\t\t\treturn nil, nil, fmt.Errorf(\"failed to get metadata of file: %w\", err)\n\t\t}\n\n\t\tmetadataStm = append(metadataStm, lo.FilterMap(fileMetadata, func(metadata *ent.Metadata, index int) (*ent.MetadataCreate, bool) {\n\t\t\tif lo.Contains(args.ExcludedMetadataKeys, metadata.Name) {\n\t\t\t\treturn nil, false\n\t\t\t}\n\t\t\treturn f.client.Metadata.Create().\n\t\t\t\tSetName(metadata.Name).\n\t\t\t\tSetValue(metadata.Value).\n\t\t\t\tSetFile(newFile).\n\t\t\t\tSetIsPublic(metadata.IsPublic), true\n\t\t})...)\n","sourceCodeStart":625,"sourceCodeEnd":661,"githubUrl":"https://github.com/cloudreve/cloudreve/blob/20c95ad73f3a8bcb72887fea91ff31ab24fa1011/inventory/file.go#L625-L661","documentation":"Thrown by File.Copy when saving one of the new file rows fails (stm.Save(ctx)). Copy inserts clones of the source files into destination folders; the most common concrete cause is a unique-constraint violation on (parent, owner, name) when a file with the same name already exists at the destination.","triggerScenarios":"Copying into a folder that already contains a file with the identical name; connection/driver failure; a NOT NULL field left unset because source rows predate a schema change; context cancelled mid-loop.","commonSituations":"Web UI copy without rename policy collides with existing destination file; two concurrent copies of the same source into the same folder race the uniqueness check; copying legacy rows missing fields required by newer ent codegen.","solutions":["Check for name collisions in the destination before copying, or implement rename-on-conflict (append suffix)","Unwrap to confirm whether it is a duplicate-key error vs driver failure","Pre-download/validate source rows against the current schema before copying","Retry only for transient driver causes, not for unique violations"],"exampleFix":"// before\nnewFiles, diff, err := inv.Copy(ctx, &inventory.CopyParameter{Files: files, DstMap: dst})\n\n// after\n// resolve name conflicts first\nfor _, f := range files {\n    if exists, _ := inv.IsNameAvailable(ctx, dstOwner, dstParent, f.Name); !exists {\n        f.Name = uniquify(f.Name)\n    }\n}\nnewFiles, diff, err := inv.Copy(ctx, &inventory.CopyParameter{Files: files, DstMap: dst})","handlingStrategy":"validation","validationCode":"// pre-check destination name availability\nfor _, f := range files {\n    if taken, _ := inv.IsChildExist(ctx, dstParent, dstOwner, f.Name); taken {\n        return fmt.Errorf(\"destination already has %q; rename first\", f.Name)\n    }\n}","typeGuard":null,"tryCatchPattern":"if _, _, err := inv.Copy(ctx, params); err != nil {\n    var mysqlErr *mysql.MySQLError\n    if errors.As(err, &mysqlErr) && mysqlErr.Number == 1062 {\n        return fmt.Errorf(\"name conflict at destination: %w\", err)\n    }\n    return err\n}","preventionTips":["Resolve name conflicts before Copy (rename or merge policy)","Lock or queue copies sharing a source file","Don't blind-retry unique-violation failures"],"tags":["go","ent","database","copy","unique-constraint"],"backgroundTag":null,"analyzedSha":"20c95ad73f3a8bcb72887fea91ff31ab24fa1011","analyzedAt":"2026-08-16T01:42:55.403Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}