List a missing file:// destination directory as an error #238

Merged
clawbot merged 1 commits from issue-220-missing-file-destination into next 2026-10-06 08:46:18 +02:00
Collaborator

Fixes #220.

The file backend listed a destination directory that does not exist as an empty store. List and ListStream now fail when the destination directory is missing. A missing prefix under an existing directory is still an empty listing, and the first write still creates the directory.

No command code changed. snapshot list, snapshot remove and prune already had a path for a store that cannot be listed, and now take it: snapshot list warns and shows the local index, snapshot remove warns that the metadata could not be removed from the destination, and prune stops with an error before deleting any local record.

What the diff does not show:

  • snapshot purge also stops with an error on a missing destination directory; it used to drop every local snapshot record the same way prune did.
  • Before the first backup, snapshot list now warns that the destination cannot be listed and remote info fails, because the directory does not exist yet.
  • Tests that listed a file:// destination nothing had created now create it: writeHermeticPruneConfig, TestInterruptedBlobUploadRecordsNoUploadedBlob, TestEntryJSONStdoutIsExactlyOneDocument.
  • Not covered: a destination configured at a mount point itself (file:///mnt/backups) leaves an empty directory behind when unmounted, which still lists as an empty store.

Judgement call: the definition of done says snapshot remove and prune delete no local record. I applied that to prune; snapshot remove still removes the named snapshot from the local index and warns, as the README documents for an unreachable store.

Model: opus-5-5

Fixes https://git.eeqj.de/sneak/vaultik/issues/220. The file backend listed a destination directory that does not exist as an empty store. `List` and `ListStream` now fail when the destination directory is missing. A missing prefix under an existing directory is still an empty listing, and the first write still creates the directory. No command code changed. `snapshot list`, `snapshot remove` and `prune` already had a path for a store that cannot be listed, and now take it: `snapshot list` warns and shows the local index, `snapshot remove` warns that the metadata could not be removed from the destination, and `prune` stops with an error before deleting any local record. What the diff does not show: - `snapshot purge` also stops with an error on a missing destination directory; it used to drop every local snapshot record the same way `prune` did. - Before the first backup, `snapshot list` now warns that the destination cannot be listed and `remote info` fails, because the directory does not exist yet. - Tests that listed a `file://` destination nothing had created now create it: `writeHermeticPruneConfig`, `TestInterruptedBlobUploadRecordsNoUploadedBlob`, `TestEntryJSONStdoutIsExactlyOneDocument`. - Not covered: a destination configured at a mount point itself (`file:///mnt/backups`) leaves an empty directory behind when unmounted, which still lists as an empty store. Judgement call: the definition of done says `snapshot remove` and `prune` delete no local record. I applied that to `prune`; `snapshot remove` still removes the named snapshot from the local index and warns, as the README documents for an unreachable store. Model: opus-5-5
clawbot added the needs-review label 2026-10-06 06:33:22 +02:00
clawbot self-assigned this 2026-10-06 06:33:22 +02:00
Author
Collaborator
  1. internal/cli/entry_banner_test.go:173-177 and :193-200: both comments still say a file:// directory that does not exist lists as an empty store, which this change makes false. TestEntryJSONStdoutIsExactlyOneDocument never creates its store directory, so snapshot list --json now goes through the could-not-list warning branch, not the empty-store branch the comment describes. The test still passes but no longer covers that branch. Acceptable: create the store directory in that test, as was done in writeHermeticPruneConfig, and correct both comments.
  2. internal/storage/file.go:28-30: "a missing or unmounted destination cannot be listed" holds only when unmounting removes the directory. A destination configured at the mount point itself (the README's file:///mnt/backups example) leaves an empty directory behind. That directory still lists as an empty store, and prune still drops every local snapshot record. Acceptable: the comment claims only what the code does, that a destination directory that does not exist cannot be listed.

Model: opus-5-5

1. `internal/cli/entry_banner_test.go:173-177` and `:193-200`: both comments still say a `file://` directory that does not exist lists as an empty store, which this change makes false. `TestEntryJSONStdoutIsExactlyOneDocument` never creates its store directory, so `snapshot list --json` now goes through the could-not-list warning branch, not the empty-store branch the comment describes. The test still passes but no longer covers that branch. Acceptable: create the store directory in that test, as was done in `writeHermeticPruneConfig`, and correct both comments. 2. `internal/storage/file.go:28-30`: "a missing or unmounted destination cannot be listed" holds only when unmounting removes the directory. A destination configured at the mount point itself (the README's `file:///mnt/backups` example) leaves an empty directory behind. That directory still lists as an empty store, and `prune` still drops every local snapshot record. Acceptable: the comment claims only what the code does, that a destination directory that does not exist cannot be listed. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-06 07:12:31 +02:00
clawbot added 1 commit 2026-10-06 08:13:17 +02:00
The file backend listed a destination directory that does not exist as
an empty store. With the volume unplugged, snapshot list reported every
local snapshot as missing from the store, snapshot remove said it had
removed metadata it never reached, and prune dropped every local
snapshot record. List and ListStream now fail when the destination
directory is missing, so those commands take their existing path for a
store that cannot be listed. A missing prefix under an existing
directory is still an empty listing, and a first backup still creates
the directory.

Three tests listed a file:// destination nothing had created; they now
create it.

Model: opus-5-5
clawbot force-pushed issue-220-missing-file-destination from b2d0d23927 to fe66b76148 2026-10-06 08:13:17 +02:00 Compare
Author
Collaborator

Rework:

  1. TestEntryJSONStdoutIsExactlyOneDocument now creates its store directory, so snapshot list --json goes through the empty-store branch again. The hermeticConfig comment now says a test that lists the destination must create its directory, and the test's comment says it lists an empty destination directory.
  2. The NewFileStorer comment now says only that List and ListStream fail on a missing destination directory. I removed the same "unmounted volume" claim from the comment on TestFileStorerListMissingDestination. The PR body now notes that a destination configured at a mount point itself still lists as an empty store.

Model: opus-5-5

Rework: 1. `TestEntryJSONStdoutIsExactlyOneDocument` now creates its store directory, so `snapshot list --json` goes through the empty-store branch again. The `hermeticConfig` comment now says a test that lists the destination must create its directory, and the test's comment says it lists an empty destination directory. 2. The `NewFileStorer` comment now says only that `List` and `ListStream` fail on a missing destination directory. I removed the same "unmounted volume" claim from the comment on `TestFileStorerListMissingDestination`. The PR body now notes that a destination configured at a mount point itself still lists as an empty store. Model: opus-5-5
clawbot added needs-review and removed needs-rework labels 2026-10-06 08:14:04 +02:00
Author
Collaborator

Review passed.

Model: opus-5-5

Review passed. Model: opus-5-5
clawbot merged commit ea72697992 into next 2026-10-06 08:46:18 +02:00
clawbot deleted branch issue-220-missing-file-destination 2026-10-06 08:46:19 +02:00
Sign in to join this conversation.