Skip to content

Fix folder watch crash on a media path that cannot be read - #1653

Open
Dev-next-gen wants to merge 1 commit into
chidiwilliams:mainfrom
Dev-next-gen:fix/folder-watch-stat-vanished-file
Open

Dev-next-gen wants to merge 1 commit into
chidiwilliams:mainfrom
Dev-next-gen:fix/folder-watch-stat-vanished-file

Conversation

@Dev-next-gen

Copy link
Copy Markdown

A watch folder that holds a dangling symlink with a media extension stops folder watch. I dropped a single dangling.mp3 symlink pointing at a file that does not exist into the watched folder and called find_tasks():

File "buzz/widgets/transcription_task_folder_watcher.py", line 74, in find_tasks
    os.path.getsize(file_path),
FileNotFoundError: [Errno 2] No such file or directory: '/tmp/tmpvotx26pu/dangling.mp3'

os.walk returns names without stating them, and the duplicate check added in #1556 calls os.path.getsize and os.path.getmtime on every candidate path. Python builds the right hand tuple before comparing it, so the stat runs even for a path that was never emitted. The same two unguarded calls run again after task_found.emit, there after the model download, which can take minutes. Since find_tasks is the slot connected to directoryChanged, the exception ends the scan and nothing listed after the unreadable path gets queued.

A symlink is just the deterministic way to trigger it. The same stat fails when a file is deleted between the scan and the check, which is routine with "delete processed files" on, or on a network folder.

This takes the stamp once, guarded, and skips the file when it cannot be read. The stamp is reused when recording the emitted path, so the second pair of stat calls is gone as well. The duplicate check itself is unchanged, and I confirmed an mp3 already recorded in paths_emitted with its current size and mtime is still skipped.

I proved it by calling the real find_tasks() on a folder holding only the dangling symlink: it raises FileNotFoundError before the change and completes without emitting a task after it. The added test does the same and skips itself on platforms that cannot create symlinks.

Found by a defect-hunting pipeline I build and run (Dev-next-gen), using Claude Code with Anthropic's Claude Opus 5.

find_tasks() stats every candidate file to build its size+mtime stamp, but
os.walk lists names without stating them. A dangling symlink with a media
extension, or a file removed since the scan started, makes os.path.getsize
raise FileNotFoundError and aborts the whole scan, so no later file in the
folder is queued.

Take the stamp once, guarded, and skip the file when it cannot be read.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant