{"record":{"id":"eb12b51284b12915","repo":"benbjohnson/litestream","slug":"failed-to-scan-directory-s-w","errorCode":null,"errorMessage":"failed to scan directory %s: %w","messagePattern":"failed to scan directory (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/litestream/main.go","lineNumber":835,"sourceCode":"\t\treturn nil, fmt.Errorf(\"directory path is required for directory replication\")\n\t}\n\n\tif dbc.Pattern == \"\" {\n\t\treturn nil, fmt.Errorf(\"pattern is required for directory replication\")\n\t}\n\tif dbc.MetaPath != nil && dbc.MetaDir != nil {\n\t\treturn nil, fmt.Errorf(\"cannot specify both 'meta-path' and 'meta-dir'\")\n\t}\n\n\tdirPath, err := expand(dbc.Dir)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Find all SQLite databases in the directory\n\tdbPaths, err := FindSQLiteDatabases(dirPath, dbc.Pattern, dbc.Recursive)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to scan directory %s: %w\", dirPath, err)\n\t}\n\n\tif len(dbPaths) == 0 && !dbc.Watch {\n\t\treturn nil, fmt.Errorf(\"no SQLite databases found in directory %s with pattern %s\", dirPath, dbc.Pattern)\n\t}\n\n\t// Create DB instances for each found database\n\tvar dbs []*litestream.DB\n\tmetaPaths := make(map[string]string)\n\n\tfor _, dbPath := range dbPaths {\n\t\tdb, err := newDBFromDirectoryEntry(dbc, dirPath, dbPath)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to create DB for %s: %w\", dbPath, err)\n\t\t}\n\n\t\t// Validate unique meta-path to prevent replication state corruption\n\t\tif mp := db.MetaPath(); mp != \"\" {","sourceCodeStart":817,"sourceCodeEnd":853,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/cmd/litestream/main.go#L817-L853","documentation":"After expanding the directory path, NewDBsFromDirectoryConfig calls FindSQLiteDatabases to enumerate databases matching the pattern. If that filesystem scan fails (I/O error rather than merely no matches), the error is wrapped with the directory path to identify what could not be scanned.","triggerScenarios":"FindSQLiteDatabases(dirPath, pattern, recursive) returns a non-nil error — e.g. the directory disappeared between expand and scan, an I/O error occurred while reading a subdirectory, or permission errors surfaced as errors from the walk.","commonSituations":"Directory is a mount that is not yet mounted at startup; network filesystem (NFS/EFS) hiccup; symlink loop or unreadable subdirectory under a recursive scan; container volume not attached yet.","solutions":["Check that the configured directory exists and is readable by the litestream process at startup.","Read the wrapped inner error to identify the failing path/file and fix the filesystem or permission problem.","If the directory is on a network mount, add a startup dependency (systemd After=/Requires=) so the mount is ready before litestream starts.","Exclude problematic subdirectories (narrow the pattern) if a specific path is unreadable."],"exampleFix":"// before\ndirPath, _ := expand(dbc.Dir) // mount may not be ready\n\n// after\nif _, err := os.Stat(dirPath); err != nil {\n    return nil, fmt.Errorf(\"directory %s not ready: %w\", dirPath, err) // surface before scanning\n}","handlingStrategy":"validation","validationCode":"if _, err := os.Stat(dirPath); err != nil {\n    return fmt.Errorf(\"replication dir %s unavailable: %w\", dirPath, err)\n}","typeGuard":null,"tryCatchPattern":"if err := runLitestream(ctx); err != nil {\n    var scanErr *fs.PathError\n    if errors.As(err, &scanErr) {\n        log.Warnf(\"directory scan failed, retrying after mount check: %v\", err)\n    }\n}","preventionTips":["Add systemd After=/Requires= for the directory's mount unit.","Check directory permissions for the litestream user before startup.","Avoid recursive patterns over directories with unreadable subpaths."],"tags":["filesystem","litestream","directory-scan","io"],"backgroundTag":"file-read-failed","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}