{"record":{"id":"f4b05b53b5b1b870","repo":"gofr-dev/gofr","slug":"unexpected-error-stating-migration-file-w","errorCode":null,"errorMessage":"unexpected error stating migration file: %w","messagePattern":"unexpected error stating migration file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/gofr/migration/opentsdb.go","lineNumber":66,"sourceCode":"func (om *openTSDBMigrator) checkAndCreateMigrationTable(c *container.Container) error {\n\tom.mu.Lock()\n\tdefer om.mu.Unlock()\n\n\t// Ensure directory exists\n\tdir := filepath.Dir(om.filePath)\n\tif dir != \".\" {\n\t\tif err := os.MkdirAll(dir, dirPerm); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to create migration directory %q: %w\", dir, err)\n\t\t}\n\t}\n\n\t// Check if file exists and is readable\n\tif _, err := os.Stat(om.filePath); err == nil {\n\t\t// File exists, validate it's proper JSON\n\t\treturn om.validateExistingFile(c)\n\t} else if !os.IsNotExist(err) {\n\t\t// Some other error accessing the file\n\t\treturn fmt.Errorf(\"unexpected error stating migration file: %w\", err)\n\t}\n\n\t// File doesn't exist, create empty migration file\n\treturn om.createEmptyMigrationFile(c)\n}\n\n// validateExistingFile checks if the existing migration file is valid JSON.\nfunc (om *openTSDBMigrator) validateExistingFile(c *container.Container) error {\n\tfile, err := os.Open(om.filePath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to open existing migration file: %w\", err)\n\t}\n\tdefer file.Close()\n\n\tvar migrations []tsdbMigrationRecord\n\tif err = json.NewDecoder(file).Decode(&migrations); err != nil {\n\t\tc.Errorf(\"Existing migration file is corrupted: %v\", err)\n\t\treturn fmt.Errorf(\"existing migration file contains invalid JSON: %w\", err)","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/gofr-dev/gofr/blob/187eb24962502e91f1fee856230670958b66e89c/pkg/gofr/migration/opentsdb.go#L48-L84","documentation":"Returned by checkAndCreateMigrationTable when os.Stat on the migration file fails with an error other than 'not exists' — e.g. permission denied on the path or an I/O error. The migrator can neither read nor safely create the file, so it aborts. Note the message's likely typo ('stating' for 'stat-ing').","triggerScenarios":"os.Stat(om.filePath) errors with something other than os.IsNotExist: EACCES on a parent directory, ELOOP from symlink cycles, or device-level I/O errors.","commonSituations":"Wrong ownership/permissions on the migration file's directory; broken symlink loop at the path; failing disk or detached mount; overly restrictive security contexts (SELinux/AppArmor).","solutions":["Read the wrapped OS errno to identify the stat failure","Fix permissions on the file and its parent directories (0755 dir, owner write)","Replace broken symlinks and verify the mount is healthy","Adjust SELinux/AppArmor policies if they block stat on the path"],"exampleFix":"// before\nls -l /data/gofr_migrations.json // owned by root, app runs as appuser -> stat EACCES\n// after\nchown appuser:appuser /data/gofr_migrations.json && chmod 644 /data/gofr_migrations.json","handlingStrategy":"validation","validationCode":"p := cfg.OpenTSDBMigrationFile\nif _, err := os.Stat(p); err != nil && !os.IsNotExist(err) {\n    return fmt.Errorf(\"migration file path has access problems (check perms/symlink): %w\", err)\n}\nif info, err := os.Lstat(p); err == nil && info.Mode()&os.ModeSymlink != 0 {\n    return errors.New(\"migration file is a symlink; verify target\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify file ownership and mode after any manual edits to the migration file","Avoid symlinks in migration file paths","Check SELinux/AppArmor policies when running in hardened environments","Monitor mount health for the volume hosting the migration file"],"tags":["opentsdb","migration","filesystem","permissions"],"backgroundTag":"file-stat-failed","analyzedSha":"187eb24962502e91f1fee856230670958b66e89c","analyzedAt":"2026-09-01T20:34:54.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}