juicedata/juicefs · error

already exists

Error message

%s already exists

What it means

Before cloning, clone checks the destination with os.Stat and rejects it with "%s already exists" if anything (file, directory, or symlink) already occupies the destination path. Note that if the destination ends with a separator, the source's base name is appended first, so the effective destination may differ from the argument typed.

Solutions

  1. Remove or rename the existing destination before cloning.
  2. Choose a fresh destination path (or append a timestamp/unique suffix).
  3. If the destination is a directory, make sure it does not already contain a file named after the source's base name.
  4. In scripts, guard with a test -e check or use clone's behavior to skip when it exists.

Example fix

# before
juicefs clone meta.sqlite3:0 /mnt/jfs/a /mnt/jfs/b   # /mnt/jfs/b exists
# after
rm /mnt/jfs/b
juicefs clone meta.sqlite3:0 /mnt/jfs/a /mnt/jfs/b
Defensive patterns

Strategy: validation

Validate before calling

dst := ctx.Args().Get(1)
if strings.HasSuffix(dst, "/") {
	dst = filepath.Join(dst, filepath.Base(src))
}
if _, err := os.Stat(dst); err == nil {
	return fmt.Errorf("destination %s exists; choose another", dst)
}

Try / catch

if err := clone(ctx); err != nil && strings.HasSuffix(err.Error(), "already exists") {
	// pick a unique destination and retry
	newDst := fmt.Sprintf("%s.%d", ctx.Args().Get(1), time.Now().Unix())
	log.Printf("retrying clone to %s", newDst)
}

Prevention

When it happens

Trigger: Running `juicefs clone <src> <dst>` where dst already exists; passing a trailing-slash destination directory that already contains a file with the source's base name; re-running a clone script without cleanup from a previous run.

Common situations: Retrying a failed clone without deleting the partial artifact; cloning into a directory that already holds the file; an automated pipeline re-executes the clone idempotently without a existence check.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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

Appendix: source

Thrown at cmd/clone.go:85

	srcPath := ctx.Args().Get(0)
	srcAbsPath, err := filepath.Abs(srcPath)
	if err != nil {
		return fmt.Errorf("abs of %s: %s", srcPath, err)
	}
	srcIno, err := utils.GetFileInode(srcPath)
	if err != nil {
		return fmt.Errorf("lookup inode for %s: %s", srcPath, err)
	}
	srcParentIno, err := utils.GetFileInode(filepath.Dir(srcAbsPath))
	if err != nil {
		return fmt.Errorf("lookup inode for %s: %s", filepath.Dir(srcAbsPath), err)
	}
	dst := ctx.Args().Get(1)
	if strings.HasSuffix(dst, string(filepath.Separator)) {
		dst = filepath.Join(dst, filepath.Base(srcPath))
	}
	if _, err := os.Stat(dst); err == nil {
		return fmt.Errorf("%s already exists", dst)
	} else if !os.IsNotExist(err) {
		return fmt.Errorf("stat %s: %s", dst, err)
	}
	dstAbsPath, err := filepath.Abs(dst)
	if err != nil {
		return fmt.Errorf("abs of %s: %s", dst, err)
	}

	srcMp, err := findMountpoint(srcAbsPath)
	if err != nil {
		return err
	}
	dstMp, err := findMountpoint(filepath.Dir(dstAbsPath))
	if err != nil {
		return err
	}
	if srcMp != dstMp {
		return fmt.Errorf("the clone DST path should be at the same mount point as the SRC path")

View on GitHub (pinned to c9a67b23e8)