gofr-dev/gofr · error

failed to open existing migration file: %w

Error message

failed to open existing migration file: %w

What it means

Returned by validateExistingFile when os.Open fails on an existing migration file (existence was just confirmed by Stat, so this is nearly always a permission problem or the file became inaccessible between stat and open). Migration validation aborts instead of risking a corrupted migration history.

Source

Thrown at pkg/gofr/migration/opentsdb.go:77

	// Check if file exists and is readable
	if _, err := os.Stat(om.filePath); err == nil {
		// File exists, validate it's proper JSON
		return om.validateExistingFile(c)
	} else if !os.IsNotExist(err) {
		// Some other error accessing the file
		return fmt.Errorf("unexpected error stating migration file: %w", err)
	}

	// File doesn't exist, create empty migration file
	return om.createEmptyMigrationFile(c)
}

// validateExistingFile checks if the existing migration file is valid JSON.
func (om *openTSDBMigrator) validateExistingFile(c *container.Container) error {
	file, err := os.Open(om.filePath)
	if err != nil {
		return fmt.Errorf("failed to open existing migration file: %w", err)
	}
	defer file.Close()

	var migrations []tsdbMigrationRecord
	if err = json.NewDecoder(file).Decode(&migrations); err != nil {
		c.Errorf("Existing migration file is corrupted: %v", err)
		return fmt.Errorf("existing migration file contains invalid JSON: %w", err)
	}

	c.Debugf("Found existing migration file with %d migrations", len(migrations))

	return nil
}

// createEmptyMigrationFile creates a new empty migration file.
func (om *openTSDBMigrator) createEmptyMigrationFile(c *container.Container) error {
	f, err := os.Create(om.filePath)
	if err != nil {

View on GitHub (pinned to 187eb24962)

Solutions

  1. Check the wrapped errno and run chmod/chown so the app user can read the file
  2. Verify the file still exists right before open (no concurrent deletion)
  3. Run migrations under the same user that owns the migration file
  4. Move the file to a stable app-owned directory to avoid ownership drift

Example fix

// before
-rw------- 1 root root gofr_migrations.json // app user cannot open
// after
sudo chown appuser:appuser gofr_migrations.json && sudo chmod 640 gofr_migrations.json
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.Stat(cfg.OpenTSDBMigrationFile); err == nil {
    f, err := os.Open(cfg.OpenTSDBMigrationFile)
    if err != nil { return fmt.Errorf("app user cannot read migration file: %w", err) }
    f.Close()
}

Prevention

When it happens

Trigger: os.Open(om.filePath) errors even though os.Stat succeeded: file mode blocks the current user (EACCES), the file was deleted by a concurrent process, or open is blocked by security policy.

Common situations: Migration file created by root during an earlier run but the app now runs as a non-root user; umask/permissions too strict after a manual edit; container user changed in a new image version.

Related errors


AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01). Data as JSON: /api/errors/9053fa835b927bee. Report an issue: GitHub.