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

  1. Check that the directory of the configured migration file path exists and is writable
  2. Fix the filePath configuration for the OpenTSDB datasource
  3. Ensure the process user has write permissions at that path
  4. 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

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


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