hasura/graphql-engine · error

unable to move migrations from project for: %v : %w

Error message

unable to move migrations from project for: %v : %w

What it means

Thrown by moveMigrations during a squash operation when MoveToDir fails to move a version's migration files into the destination directory. The %v is the migration version and %w the underlying filesystem error. It aborts the squash, leaving some versions possibly already moved.

Source

Thrown at cli/commands/migrate_squash.go:326

func moveMigrations(
	ec *cli.ExecutionContext,
	versions []uint64,
	source cli.Source,
	destination string,
) error {
	var op errors.Op = "commands.moveMigrations"

	for _, v := range versions {
		moveOpts := mig.CreateOptions{
			Version:   strconv.FormatUint(v, 10),
			Directory: filepath.Join(ec.MigrationDir, source.Name),
		}

		err := moveOpts.MoveToDir(destination)
		if err != nil {
			return errors.E(
				op,
				fmt.Errorf("unable to move migrations from project for: %v : %w", v, err),
			)
		}
	}

	return nil
}

func ask2confirmDeleteMigrations(
	versions []int64,
	squashedDirectoryName string,
	log *logrus.Logger,
) bool {
	log.Infof("The following migrations are squashed into a new one:")

	out := new(tabwriter.Writer)
	buf := &bytes.Buffer{}
	out.Init(buf, 0, 8, 2, ' ', 0)

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Check permissions on the migrations directory and destination (chown/chmod) and re-run squash
  2. Clean up partial results of the failed squash (delete leftover destination dirs) and retry
  3. Verify no other process locks the migrations directory (editor, watcher, antivirus) and re-run
  4. If in a container/CI, ensure the project volume is mounted read-write

Example fix

# before: squash fails with 'unable to move migrations from project for: 42 : ...'
ls -la migrations/  # inspect leftover dirs and permissions
chmod -R u+w migrations/ && rm -rf migrations/_temp_squash
# after: re-run the squash command
hasura migrate squash --name squashed --from 42
Defensive patterns

Strategy: validation

Validate before calling

// before squashing, verify migration dirs are movable
for _, v := range versions {
    dir := filepath.Join(migrationsDir, fmt.Sprintf("%d", v))
    if fi, err := os.Stat(dir); err != nil || !fi.IsDir() {
        return fmt.Errorf("migration dir %s missing or not a directory", dir)
    }
    if err := unix.Access(dir, unix.W_OK); err != nil {
        return fmt.Errorf("no write permission on %s", dir)
    }
}

Try / catch

Catch errors.E around moveMigrations, unwrap with errors.Unwrap to inspect the underlying *os.PathError and decide between retry and abort; report the failing version from the message.

Prevention

When it happens

Trigger: Running 'hasura migrate squash' when the migrations directory for version %v cannot be moved into the destination dir — e.g. permission denied, destination already exists, read-only filesystem, or the migrations dir layout has unexpected files/dirs.

Common situations: Non-writable project dir, migrations dir owned by another user, leftover directories from a previous failed squash, running the CLI inside a container with a read-only mount, or path length/character issues on Windows.

Related errors


AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28). Data as JSON: /api/errors/e0995bb2e4868433. Report an issue: GitHub.