dagger/dagger · error

failed to lstat file target

Error message

failed to lstat file target

What it means

ensureEmptyFileTarget lstats the destination before copying a file over it; if Lstat fails with an error other than NotExist, this wrapped error is returned. It indicates the destination path could not even be inspected — permissions on the parent directory, a bad path, or I/O errors — not that the file is absent.

Source

Thrown at internal/fsutil/copy/copy.go:696

		}
		return true, nil
	} else if !st.IsDir() {
		return false, errors.Errorf("cannot copy to non-directory: %s", dst)
	} else if overwriteTargetMetadata {
		if err := os.Chmod(dst, stat.Mode()); err != nil {
			return false, errors.Wrapf(err, "failed to chmod on %s", dst)
		}
	}
	return false, nil
}

func ensureEmptyFileTarget(dst string) error {
	fi, err := os.Lstat(dst)
	if err != nil {
		if os.IsNotExist(err) {
			return nil
		}
		return errors.Wrap(err, "failed to lstat file target")
	}
	if fi.IsDir() {
		return errors.Errorf("cannot replace to directory %s with file", dst)
	}
	return os.Remove(dst)
}

func containsWildcards(name string) bool {
	isWindows := runtime.GOOS == "windows"
	for i := 0; i < len(name); i++ {
		ch := name[i]
		if ch == '\\' && !isWindows {
			i++
		} else if ch == '*' || ch == '?' || ch == '[' {
			return true
		}
	}
	return false

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Inspect the wrapped os error and fix parent-directory permissions so the path can be stat'ed
  2. Validate the destination path components exist and are traversable directories
  3. Check for symlink loops or broken mounts on the destination path
  4. Shorten the destination path if hitting ENAMETOOLONG

Example fix

// before
copy.Copy(ctx, srcFS, "/src/file", "/root-only-dir/file") // lstat EACCES
// after
if _, err := os.Lstat("/root-only-dir"); err != nil {
    return fmt.Errorf("dest parent inaccessible: %w", err)
}
copy.Copy(ctx, srcFS, "/src/file", "/root-only-dir/file")
Defensive patterns

Strategy: validation

Validate before calling

for dir := filepath.Dir(dst); dir != "/"; dir = filepath.Dir(dir) {
    if _, err := os.Lstat(dir); err != nil {
        return fmt.Errorf("cannot stat path component %s: %w", dir, err)
    }
}

Type guard

func pathStatable(p string) error {
    _, err := os.Lstat(p)
    if err == nil || os.IsNotExist(err) {
        return nil
    }
    return err
}

Try / catch

if err := copy.Copy(ctx, srcFS, src, dst); err != nil {
    if strings.Contains(err.Error(), "failed to lstat file target") {
        return fmt.Errorf("destination %s is not inspectable: check parent permissions/mounts: %w", dst, err)
    }
    return err
}

Prevention

When it happens

Trigger: copy() of a file to dst where os.Lstat(dst) returns a non-IsNotExist error (EACCES on parent dir, ENOTDIR via a non-dir path component, EIO, ENAMETOOLONG).

Common situations: Destination path traverses a directory without execute permission; dst contains a symlink loop or corrupted mount; path length exceeds filesystem limits.

Related errors


AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05). Data as JSON: /api/errors/8efba04adea16db0. Report an issue: GitHub.