gofr-dev/gofr · error
failed to create migration file: received nil file handle
Error message
failed to create migration file: received nil file handle
What it means
errNilFileHandle is returned by createEmptyMigrationFile when the file-creation path yields a nil *os.File handle, i.e., the migrator could not obtain a valid handle for the OpenTSDB migration file. This is a defensive guard against proceeding with a nil file that would panic on write/close.
Source
Thrown at pkg/gofr/migration/opentsdb.go:36
filePath string
}
type openTSDBMigrator struct {
filePath string
migrator
mu sync.Mutex
}
type tsdbMigrationRecord struct {
Version int64 `json:"version"`
Method string `json:"method"`
StartTime string `json:"start_time"`
Duration int64 `json:"duration"`
}
const dirPerm = 0755
var errNilFileHandle = errors.New("failed to create migration file: received nil file handle")
// apply initializes openTSDBMigrator using the openTsdbDS.
func (ds openTSDBDS) apply(m migrator) migrator {
return &openTSDBMigrator{ // Return pointer to avoid copying the mutex
filePath: ds.filePath,
migrator: m,
}
}
// checkAndCreateMigrationTable ensures the migration directory and file structure exists.
// It only creates an empty file if no migration file exists at all.
func (om *openTSDBMigrator) checkAndCreateMigrationTable(c *container.Container) error {
om.mu.Lock()
defer om.mu.Unlock()
// Ensure directory exists
dir := filepath.Dir(om.filePath)
if dir != "." {View on GitHub (pinned to 187eb24962)
Solutions
- Check that the directory of the configured migration file path exists and is writable
- Fix the filePath configuration for the OpenTSDB datasource
- Ensure the process user has write permissions at that path
- Pre-create the parent directory (the migrator uses dirPerm 0755 via MkdirAll)
Example fix
// before filePath: "/mnt/ro-fs/gofr_migrations.json" // read-only mount -> nil handle // after filePath: "/var/lib/app/gofr_migrations.json" // writable location
Defensive patterns
Strategy: validation
Validate before calling
dir := filepath.Dir(cfg.OpenTSDBMigrationFile)
if err := os.MkdirAll(dir, 0755); err != nil {
return fmt.Errorf("cannot prepare migration dir: %w", err)
}
f, err := os.OpenFile(cfg.OpenTSDBMigrationFile, os.O_CREATE|os.O_WRONLY, 0644)
if err != nil || f == nil {
return errors.New("migration file path not writable")
}
f.Close() Type guard
func validFileHandle(f *os.File) bool { return f != nil } Prevention
- Configure filePath under a directory known to be writable by the app user
- Pre-create the migration directory in your deploy/Dockerfile
- Avoid read-only root filesystems for migration file storage (use a volume)
- Test migrations in the container image with the same user it runs as
When it happens
Trigger: createEmptyMigrationFile gets a nil file handle after attempting to create the migration file — typically an OS-level create failure path that slipped past the error check, or a nil result from the file-creation helper.
Common situations: Read-only filesystem or missing/uncreatable parent directory for the migration file path; permission denied; misconfigured filePath pointing into a nonexistent mount.
Related errors
- failed to create migration directory %q: %w
- unexpected error stating migration file: %w
- failed to open existing migration file: %w
- failed to read CA certificate from %s: %w
- file does not have read permission: %w
AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01).
Data as JSON: /api/errors/374f674d67b3b4d3.
Report an issue: GitHub.