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
- Check the wrapped errno and run chmod/chown so the app user can read the file
- Verify the file still exists right before open (no concurrent deletion)
- Run migrations under the same user that owns the migration file
- 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
- Run the app and migrations as the same OS user to prevent ownership drift
- chmod 640 + correct group ownership on the migration file
- Add a readable-file check to your startup/pre-flight script
- Never run migrations as root in an environment where the app runs as a non-root user
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
- failed to create migration directory %q: %w
- unexpected error stating migration file: %w
- failed to create migration file: received nil file handle
- file does not have read permission: %w
- failed to delete object
AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01).
Data as JSON: /api/errors/9053fa835b927bee.
Report an issue: GitHub.