cloudreve/cloudreve · error
failed to delete direct links of files %v: %w
Error message
failed to delete direct links of files %v: %w
What it means
Wraps a failure to hard-delete direct-link rows attached to the files being removed (DirectLink.Delete().Where(directlink.FileIDIn(...)) under SkipSoftDelete). Direct links are signed URLs bypassing shares; they must be physically removed with the file.
Source
Thrown at inventory/file.go:596
hardDeleteCtx := schema.SkipSoftDelete(ctx)
fileGroups, chunks := f.batchInCondition(intsets.MaxInt, 10, 1,
lo.Map(files, func(file *ent.File, index int) int {
return file.ID
}),
)
for i, group := range fileGroups {
// 4. Delete shares/metadata/directlinks if needed;
if _, err := f.client.Share.Delete().Where(share.HasFileWith(group)).Exec(ctx); err != nil {
return nil, nil, fmt.Errorf("failed to delete shares of files %v: %w", group, err)
}
if _, err := f.client.Metadata.Delete().Where(metadata.FileIDIn(chunks[i]...)).Exec(schema.SkipSoftDelete(ctx)); err != nil {
return nil, nil, fmt.Errorf("failed to delete metadata of files %v: %w", group, err)
}
if _, err := f.client.DirectLink.Delete().Where(directlink.FileIDIn(chunks[i]...)).Exec(hardDeleteCtx); err != nil {
return nil, nil, fmt.Errorf("failed to delete direct links of files %v: %w", group, err)
}
// 5. Delete files.
if _, err := f.client.File.Delete().Where(group).Exec(hardDeleteCtx); err != nil {
return nil, nil, fmt.Errorf("failed to delete files %v: %w", group, err)
}
}
return toBeRecycled, storageReduced, nil
}
func (f *fileClient) Copy(ctx context.Context, args *CopyParameter) (map[int][]*ent.File, StorageDiff, error) {
files := args.Files
dstMap := args.DstMap
pageSize := capPageSize(f.maxSQlParam, intsets.MaxInt, 10)
// 1. Copy files and metadata
copyFileStm := lo.Map(files, func(file *ent.File, index int) *ent.FileCreate {
View on GitHub (pinned to 20c95ad73f)
Solutions
- Unwrap the underlying cause; retry deadlock-class failures
- Re-invoke the delete to finish remaining batches
- Review any schema-level FKs added to direct_links
- Tolerate 404-style outcomes in link consumers when a file is removed mid-download
Example fix
// before
inv.Delete(ctx, files, props)
// after
if err := deleteAll(files); isDeadlockOrConnReset(err) {
// links are removed per batch; second pass completes the remainder
err = deleteAll(files)
} Defensive patterns
Strategy: try-catch
Try / catch
if _, _, err := inv.Delete(ctx, files, props); err != nil {
log.WithError(err).Warn("direct-link purge failed; rerunning delete to finish")
if _, err2 := inv.Delete(ctx, remainingFiles(ctx, files), props); err2 != nil {
return errors.Join(err, err2)
}
} Prevention
- Expect link consumers to 404 once the source file deletion begins
- Re-run deletes to complete link removal
- Audit custom FKs on direct_links
When it happens
Trigger: Concurrent creation or use of a direct link on a file being deleted (lock contention); FK RESTRICT from customized schema; connection/context failure mid-cascade.
Common situations: Download via direct link racing file deletion; large-batch deletes crossing a DB restart; schema customization adding FKs to the direct_links table.
Related errors
- failed to delete metadata of files %v: %w
- failed to delete files %v: %w
- failed to delete shares of files %v: %w
- failed to create group %q: %w
- failed creating schema resources: %w
AI-assisted analysis of cloudreve/cloudreve@20c95ad73f (2026-08-16).
Data as JSON: /api/errors/3c24046380303a8e.
Report an issue: GitHub.