juicedata/juicefs · error

%s is non-empty directory

Error message

%s is non-empty directory

What it means

webdav.Delete refuses to remove a collection (directory) that still contains entries. It PROPFINDs the target; if not found it's already gone, but if entries exist it returns "<key> is non-empty directory" instead of recursing.

Source

Thrown at pkg/object/webdav.go:102

func (w *webdav) Delete(ctx context.Context, key string, getters ...AttrGetter) error {
	info, err := w.c.Stat(key)
	if gowebdav.IsErrNotFound(err) {
		return nil
	}
	if err != nil {
		return err
	}
	if info.IsDir() {
		infos, err := w.c.ReadDir(key)
		if err != nil {
			if gowebdav.IsErrNotFound(err) {
				return nil
			}
			return err
		}
		if len(infos) != 0 {
			return fmt.Errorf("%s is non-empty directory", key)
		}
	}
	return w.c.Remove(key)
}

func (w *webdav) Copy(ctx context.Context, dst, src string) error {
	return w.c.Copy(src, dst, true)
}

type webDAVFile struct {
	os.FileInfo
	name string
}

func (w webDAVFile) Name() string {
	return w.name
}

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Empty the directory first (delete children), then delete the directory
  2. Use a recursive delete at the application level before calling Delete
  3. Check the server's PROPFIND result — some servers return phantom entries; verify real children exist
  4. If the directory is actually empty, the listing may be stale — retry

Example fix

// before
store.Delete(ctx, "photos/")
// after
objs, _ := store.List(ctx, "photos/", "", -1, true)
for _, o := range objs { store.Delete(ctx, o.Key()) }
store.Delete(ctx, "photos/")
Defensive patterns

Strategy: fallback

Validate before calling

func dirEmpty(ctx context.Context, w object.ObjectStorage, key string) (bool, error) {
	objs, _, err := w.List(ctx, key, "", 1, true)
	if err != nil { return false, err }
	return len(objs) == 0, nil
}

Try / catch

err := store.Delete(ctx, key)
if err != nil && strings.HasSuffix(err.Error(), "is non-empty directory") {
	// list children, delete each, then delete the directory
}

Prevention

When it happens

Trigger: Deleting a WebDAV directory path that has children; also hit during garbage collection or cleanup operations that walk keys resembling directories.

Common situations: Deleting a 'folder-like' object left by another client; mount point cleanup where empty-dir detection disagrees (server returns implicit entries); keys ending in '/' that other clients populated.

Related errors


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/cb33fe8d1a58ca95. Report an issue: GitHub.