{"record":{"id":"9053fa835b927bee","repo":"gofr-dev/gofr","slug":"failed-to-open-existing-migration-file-w","errorCode":null,"errorMessage":"failed to open existing migration file: %w","messagePattern":"failed to open existing migration file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/gofr/migration/opentsdb.go","lineNumber":77,"sourceCode":"\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)\n\t}\n\n\tc.Debugf(\"Found existing migration file with %d migrations\", len(migrations))\n\n\treturn nil\n}\n\n// createEmptyMigrationFile creates a new empty migration file.\nfunc (om *openTSDBMigrator) createEmptyMigrationFile(c *container.Container) error {\n\tf, err := os.Create(om.filePath)\n\tif err != nil {","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/gofr-dev/gofr/blob/187eb24962502e91f1fee856230670958b66e89c/pkg/gofr/migration/opentsdb.go#L59-L95","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n-rw------- 1 root root gofr_migrations.json // app user cannot open\n// after\nsudo chown appuser:appuser gofr_migrations.json && sudo chmod 640 gofr_migrations.json","handlingStrategy":"validation","validationCode":"if _, err := os.Stat(cfg.OpenTSDBMigrationFile); err == nil {\n    f, err := os.Open(cfg.OpenTSDBMigrationFile)\n    if err != nil { return fmt.Errorf(\"app user cannot read migration file: %w\", err) }\n    f.Close()\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["opentsdb","migration","filesystem","permissions"],"backgroundTag":"file-open-permission-denied","analyzedSha":"187eb24962502e91f1fee856230670958b66e89c","analyzedAt":"2026-09-01T20:34:54.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}