hasura/graphql-engine · error

cannot read file %s: %w

Error message

cannot read file %s: %w

What it means

Thrown by IsEmptyFile, which Scan calls for every migration file to skip empty ones: it does os.ReadFile on migrations/<raw-name> and any read failure is wrapped as 'cannot read file <name>'. Typical causes are a missing file, permission errors, or path/permission issues where the CLI runs.

Source

Thrown at cli/migrate/source/parse.go:125

		}

		return &Migration{
			Version:    versionUint64,
			Identifier: m[2],
			Direction:  direction,
		}, nil
	}

	return nil, errors.E(op, ErrParse)
}

// Validate file to check for empty sql or yaml content.
func IsEmptyFile(m *Migration, directory string) (bool, error) {
	var op errors.Op = "source.IsEmptyFile"

	data, err := os.ReadFile(filepath.Join(directory, m.Raw))
	if err != nil {
		return false, errors.E(op, fmt.Errorf("cannot read file %s: %w", m.Raw, err))
	}

	switch direction := m.Direction; direction {
	case MetaUp, MetaDown:
		var t []any

		err = yaml.Unmarshal(data, &t)
		if err != nil {
			return false, errors.E(op, fmt.Errorf("invalid yaml file: %s: %w", m.Raw, err))
		}

		if len(t) == 0 {
			return false, nil
		}
	case Up, Down:
		if string(data) == "" {
			return false, nil
		}

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Verify every file listed in migrations/ actually exists: ls the directory and compare with the error's file name
  2. Restore the missing file from git (git status / git checkout -- migrations/)
  3. Check read permissions for the running user on the migrations directory
  4. Ensure you run migrate commands from the project root so the relative directory resolves

Example fix

# before
$ rm migrations/05_old.up.sql && hasura migrate apply
# cannot read file 05_old.up.sql

# after
$ git checkout -- migrations/05_old.up.sql && hasura migrate apply
Defensive patterns

Strategy: validation

Validate before calling

// Verify every migration file is readable before scanning
for m := range expectedMigrations {
    if _, err := os.Stat(filepath.Join("migrations", m)); err != nil {
        return fmt.Errorf("migration file missing: %s", m)
    }
}

Try / catch

if _, err := source.IsEmptyFile(m, dir); err != nil {
    if strings.Contains(err.Error(), "cannot read file") {
        // restore missing/unreadable file from VCS
    }
}

Prevention

When it happens

Trigger: A Migration entry whose m.Raw file doesn't exist on disk (deleted or renamed after the directory listing), running the CLI without read permission on migrations/, or a directory value that doesn't match where files live (symlink/oddx case). Any migrate command that scans the source triggers it.

Common situations: Deleting or renaming migration files while another process/CI job runs; checking out a repo on a case-sensitive filesystem after files were renamed with different case; read-only mounts; stale editor state referencing removed files.

Related errors


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