cloudreve/cloudreve · error

failed to get folder: %w

Error message

failed to get folder: %w

What it means

After the folder upsert returned an id, the follow-up f.client.File.Get(ctx, fid) failed to fetch the row. Usually fid is 0 or stale (the conflict-ignored upsert path can yield no usable id, see error 175), the folder was deleted immediately after creation, or the database errored.

Source

Thrown at inventory/file.go:1082

func (f *fileClient) CreateFolder(ctx context.Context, root *ent.File, args *CreateFolderParameters) (*ent.File, error) {
	stm := f.client.File.
		Create().
		SetOwnerID(args.Owner).
		SetType(int(types.FileTypeFolder)).
		SetIsSymbolic(args.IsSymbolic).
		SetName(args.Name)
	if root != nil {
		stm.SetParent(root).SetType(int(types.FileTypeFolder))
	}

	fid, err := stm.OnConflict(sql.ConflictColumns(file.FieldFileChildren, file.FieldName)).Ignore().ID(ctx)
	if err != nil {
		return nil, fmt.Errorf("failed to create folder: %w", err)
	}

	newFolder, err := f.client.File.Get(ctx, fid)
	if err != nil {
		return nil, fmt.Errorf("failed to get folder: %w", err)
	}

	if len(args.Metadata) > 0 {
		_, err := f.client.Metadata.
			CreateBulk(lo.MapToSlice(args.Metadata, func(key, value string) *ent.MetadataCreate {
				_, isPrivate := args.MetadataPrivateMask[key]
				return f.client.Metadata.Create().
					SetName(key).
					SetValue(value).
					SetFile(newFolder).
					SetIsPublic(!isPrivate)
			})...).
			Save(ctx)
		if err != nil {
			return nil, fmt.Errorf("failed to create metadata: %v", err)
		}
	}

View on GitHub (pinned to 20c95ad73f)

Solutions

  1. If fid == 0 after an ignored conflict, resolve the folder by (parent, name) instead of Get-by-id
  2. Retry the Get once on transient driver errors
  3. Check the wrapped error with ent.IsNotFound to branch to a name-based lookup

Example fix

// before
newFolder, err := f.client.File.Get(ctx, fid)
// after
newFolder, err := f.client.File.Get(ctx, fid)
if err != nil && ent.IsNotFound(err) && root != nil {
	newFolder, err = f.client.File.Query().Where(file.HasParentWith(file.ID(root.ID)), file.Name(args.Name)).Only(ctx)
}
Defensive patterns

Strategy: fallback

Try / catch

folder, err := f.CreateFolder(ctx, root, args)
if err != nil {
	if ent.IsNotFound(err) && root != nil {
		if existing, qerr := f.client.File.Query().Where(file.HasParentWith(file.ID(root.ID)), file.Name(args.Name)).Only(ctx); qerr == nil {
			folder = existing
			err = nil
		}
	}
	if err != nil {
		return nil, err
	}
}

Prevention

When it happens

Trigger: Upsert conflict returned id 0 and Get looks up a non-existent row; concurrent delete between upsert and Get; connection failure.

Common situations: Same scenarios as the folder-create conflict: idempotent re-runs and concurrent folder creation.

Related errors


AI-assisted analysis of cloudreve/cloudreve@20c95ad73f (2026-08-16). Data as JSON: /api/errors/0309f318134dfdb1. Report an issue: GitHub.