{"record":{"id":"03d2996dfe603ce1","repo":"gofr-dev/gofr","slug":"failed-to-create-migration-directory-q-w","errorCode":null,"errorMessage":"failed to create migration directory %q: %w","messagePattern":"failed to create migration directory %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/gofr/migration/opentsdb.go","lineNumber":56,"sourceCode":"// apply initializes openTSDBMigrator using the openTsdbDS.\nfunc (ds openTSDBDS) apply(m migrator) migrator {\n\treturn &openTSDBMigrator{ // Return pointer to avoid copying the mutex\n\t\tfilePath: ds.filePath,\n\t\tmigrator: m,\n\t}\n}\n\n// checkAndCreateMigrationTable ensures the migration directory and file structure exists.\n// It only creates an empty file if no migration file exists at all.\nfunc (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 {","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/gofr-dev/gofr/blob/187eb24962502e91f1fee856230670958b66e89c/pkg/gofr/migration/opentsdb.go#L38-L74","documentation":"Thrown by checkAndCreateMigrationTable when os.MkdirAll cannot create the directory that should contain the OpenTSDB migration file. The wrapped error identifies the OS-level cause (permissions, path is a file, read-only FS). Migration setup aborts before any migration runs.","triggerScenarios":"filepath.Dir(om.filePath) is not \".\" and os.MkdirAll(dir, 0755) fails: parent not writable, a path component exists as a regular file, or the filesystem is read-only.","commonSituations":"filePath configured as /etc/gofr_migrations.json (no write perms); a file occupies what should be a directory; running in a locked-down container rootfs; NFS mount gone read-only.","solutions":["Make the parent directory writable or choose a writable filePath (e.g. /var/lib/app)","Check the wrapped OS error — EACCES vs ENOTDIR vs EROFS","Remove/replace any regular file that conflicts with the directory path","Pre-create the directory with correct ownership before deploying"],"exampleFix":"// before\nfilePath: \"/etc/gofr_migrations.json\" // MkdirAll(/etc) fails: permission denied\n// after\nfilePath: \"/var/lib/myapp/gofr_migrations.json\"","handlingStrategy":"validation","validationCode":"dir := filepath.Dir(cfg.OpenTSDBMigrationFile)\nif info, err := os.Stat(dir); err == nil && !info.IsDir() {\n    return fmt.Errorf(\"%s exists but is a file; remove it so a directory can be created\", dir)\n}\nif err := os.MkdirAll(dir, 0755); err != nil {\n    return fmt.Errorf(\"pre-flight mkdir failed: %w\", err)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never place the migration file under system dirs like /etc or /usr","Ensure no regular file occupies the would-be directory path","Grant the app user write permission on the parent path","Run pre-flight mkdir in your deployment script before the app starts"],"tags":["opentsdb","migration","filesystem","permissions"],"backgroundTag":"mkdir-permission-denied","analyzedSha":"187eb24962502e91f1fee856230670958b66e89c","analyzedAt":"2026-09-01T20:34:54.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}