From a26777f1dd6b2c18411312e99dc75b710b02ef2e Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 1 Mar 2026 13:35:08 +0000 Subject: [PATCH] fix: fall back to PollingObserver when inotify is unavailable Recursive inotify fails with EIO on some Docker volume drivers and old kernels (e.g. Linux 4.4). Catch the OSError from observer.start() and retry with PollingObserver, which polls the filesystem and works on any mount type. https://claude.ai/code/session_01RAgDPoriuh3iLQahcQDEEz --- backend/ingestion.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/backend/ingestion.py b/backend/ingestion.py index ffa5ed1..7f954e8 100644 --- a/backend/ingestion.py +++ b/backend/ingestion.py @@ -19,6 +19,7 @@ from dotenv import load_dotenv from watchdog.events import FileSystemEventHandler from watchdog.observers import Observer +from watchdog.observers.polling import PollingObserver # Add parent to path for imports sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) @@ -201,12 +202,20 @@ def main() -> None: if count: logger.info("Processed %d existing file(s) from import dir", count) - # Start watching + # Start watching — fall back to polling if inotify is unavailable (e.g. NFS, + # certain Docker volume drivers, or kernels that don't support recursive inotify) handler = RawFileHandler() observer = Observer() observer.schedule(handler, IMPORT_DIR, recursive=True) - observer.start() - logger.info("👁 Watching for new files in: %s", os.path.abspath(IMPORT_DIR)) + try: + observer.start() + logger.info("👁 Watching (inotify) for new files in: %s", os.path.abspath(IMPORT_DIR)) + except OSError as exc: + logger.warning("inotify unavailable (%s), falling back to polling observer", exc) + observer = PollingObserver() + observer.schedule(handler, IMPORT_DIR, recursive=True) + observer.start() + logger.info("👁 Watching (polling) for new files in: %s", os.path.abspath(IMPORT_DIR)) logger.info("Press Ctrl+C to stop") try: