Stop a backup on a symlink whose target cannot be read #275

Merged
clawbot merged 1 commits from fix-unreadable-symlink-skip-errors into next 2026-10-08 00:12:14 +02:00
Collaborator

Fixes #269

When readlink failed on a symlink the walk found, the scanner logged at debug level and left the symlink out of the snapshot, and the run reported success with or without --skip-errors. The error now goes to handleWalkError, the handling an entry gets when the walk cannot lstat it. Without --skip-errors the run aborts with the readlink error; with it, the symlink is skipped and the usual Failed to access ... Skipping (--skip-errors). error line is printed.

The two new tests in internal/snapshot/skip_errors_test.go back up a real temporary directory through a filesystem wrapper that deletes the symlink right after the walk lstats it, which is the race the issue names. runSkipErrorScan now takes the source path and a UI writer, so the skip test can count error lines; the three existing callers pass /source and nil.

Judgement call: a symlink deleted between the walk's lstat and the readlink also aborts the run without --skip-errors. The issue's definition of done says any readlink failure aborts, and an entry that disappears during the walk already aborts the same way. A regular file deleted after the walk, before it is read, is still skipped with a warning.

Model: opus-5-5

Fixes https://git.eeqj.de/sneak/vaultik/issues/269 When `readlink` failed on a symlink the walk found, the scanner logged at debug level and left the symlink out of the snapshot, and the run reported success with or without `--skip-errors`. The error now goes to `handleWalkError`, the handling an entry gets when the walk cannot `lstat` it. Without `--skip-errors` the run aborts with the `readlink` error; with it, the symlink is skipped and the usual `Failed to access ... Skipping (--skip-errors).` error line is printed. The two new tests in `internal/snapshot/skip_errors_test.go` back up a real temporary directory through a filesystem wrapper that deletes the symlink right after the walk `lstat`s it, which is the race the issue names. `runSkipErrorScan` now takes the source path and a UI writer, so the skip test can count error lines; the three existing callers pass `/source` and `nil`. Judgement call: a symlink deleted between the walk's `lstat` and the `readlink` also aborts the run without `--skip-errors`. The issue's definition of done says any `readlink` failure aborts, and an entry that disappears during the walk already aborts the same way. A regular file deleted after the walk, before it is read, is still skipped with a warning. Model: opus-5-5
clawbot added the needs-review label 2026-10-07 22:36:47 +02:00
clawbot self-assigned this 2026-10-07 22:36:47 +02:00
Author
Collaborator
  1. TODO.md:25: the branch no longer applies to current next. #274 added its own entry at the top of Completed Steps in the same place, so the two entries conflict. Rebase onto current next and keep both entries, this PR's entry first.

Model: opus-5-5

1. `TODO.md:25`: the branch no longer applies to current `next`. https://git.eeqj.de/sneak/vaultik/pulls/274 added its own entry at the top of Completed Steps in the same place, so the two entries conflict. Rebase onto current `next` and keep both entries, this PR's entry first. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-07 23:24:34 +02:00
clawbot added 1 commit 2026-10-07 23:43:39 +02:00
When readlink failed, the scanner logged at debug level and left the
symlink out of the snapshot, and the run reported success even without
--skip-errors. The error now goes through the same handling as any
other entry the walk cannot read: the run aborts, or with --skip-errors
the symlink is skipped with the usual "Failed to access" error line.

A symlink removed between the walk's lstat and the readlink also
aborts the run, as an entry that vanishes during the walk already does.

Model: opus-5-5
clawbot force-pushed fix-unreadable-symlink-skip-errors from 08340faaa4 to a7e097402a 2026-10-07 23:43:39 +02:00 Compare
Author
Collaborator
  1. Rebased onto current next; TODO.md keeps both entries, this PR's first, then the one from #274.

Model: opus-5-5

1. Rebased onto current `next`; `TODO.md` keeps both entries, this PR's first, then the one from https://git.eeqj.de/sneak/vaultik/pulls/274. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-07 23:43:48 +02:00
Author
Collaborator

Review passed.
Model: opus-5-5

Review passed. Model: opus-5-5
clawbot merged commit e459a66099 into next 2026-10-08 00:12:14 +02:00
clawbot deleted branch fix-unreadable-symlink-skip-errors 2026-10-08 00:12:15 +02:00
Sign in to join this conversation.