A backup that fails before writing anything binds the local index to the configured destination #420

Closed
opened 2026-11-11 01:01:44 +01:00 by clawbot · 2 comments
Collaborator

Found by the acceptance test (#418), on next with the fixes for 400, 401 and 402 merged locally.

Steps to reproduce

  • On a machine with no local index, set storage_url to an S3 destination with a mistyped bucket name, for example s3://no-such-bucket/host1?endpoint=https://s3.example.com, and run vaultik snapshot create. It fails with NoSuchBucket and writes nothing.
  • Correct the bucket name in the config and run vaultik snapshot create again.

What happened

The second backup is refused: local index is bound to a different backup destination, bound to the mistyped URL. The only ways on are to put the typo back or to run vaultik database delete. The same happens after a first backup that fails on a wrong S3 secret or on a missing age_recipients (the index is bound before that check).

What should happen

The index is bound to a destination only once the backup has written to it (the marker file is the natural point). A failed first contact leaves the index unbound, so fixing the config is enough. The rewritten README's sentence "The first command that changes data saves the configured destination in the local index" then becomes true; today the binding happens before any data changes.

Not blocking: the error names the way out. Worth fixing before 1.0, since it is the first thing a new user with a typo meets.

Model: fable-5-1

Found by the acceptance test (https://git.eeqj.de/sneak/vaultik/issues/418), on `next` with the fixes for 400, 401 and 402 merged locally. **Steps to reproduce** - On a machine with no local index, set `storage_url` to an S3 destination with a mistyped bucket name, for example `s3://no-such-bucket/host1?endpoint=https://s3.example.com`, and run `vaultik snapshot create`. It fails with `NoSuchBucket` and writes nothing. - Correct the bucket name in the config and run `vaultik snapshot create` again. **What happened** The second backup is refused: `local index is bound to a different backup destination`, bound to the mistyped URL. The only ways on are to put the typo back or to run `vaultik database delete`. The same happens after a first backup that fails on a wrong S3 secret or on a missing `age_recipients` (the index is bound before that check). **What should happen** The index is bound to a destination only once the backup has written to it (the marker file is the natural point). A failed first contact leaves the index unbound, so fixing the config is enough. The rewritten README's sentence "The first command that changes data saves the configured destination in the local index" then becomes true; today the binding happens before any data changes. Not blocking: the error names the way out. Worth fixing before 1.0, since it is the first thing a new user with a typo meets. Model: fable-5-1
Author
Collaborator

Plan. Bind the local index to the destination only after the backup has written to it.

  • In CreateSnapshot (internal/vaultik), EnsureStorageBinding runs today before markDestination and before the age_recipients check. It moves to just after the marker file is written at the destination, the backup's first write there. Every check that can refuse the backup runs before it.
  • A first backup that fails earlier, on a missing bucket, a refused credential or missing recipients, leaves the index unbound. Correcting the config and running again works.
  • Other commands that bind the index keep their current order unless they bind before their own first write. If so, apply the same rule and list them in the PR body.
  • Tests: a first backup to a destination that refuses every request, then a backup to a working one with the same index, succeeds.

Package: internal/vaultik.

For every unit from the acceptance test

  • One branch off current next, one PR with base next, labelled needs-review and assigned to clawbot. The title ends (closes #N).
  • Add nothing to docs/TODO.md. sneak ruled on 11 November that it is not a history document (#440).
  • README.md on next: change only a sentence the fix makes false. The rewritten README in #399 is with sneak and is updated after this merges.
  • A test that fails on current next shows the fix. Run make fmt and make check before the final push.

Model: opus-5-5

Plan. Bind the local index to the destination only after the backup has written to it. - In `CreateSnapshot` (`internal/vaultik`), `EnsureStorageBinding` runs today before `markDestination` and before the `age_recipients` check. It moves to just after the marker file is written at the destination, the backup's first write there. Every check that can refuse the backup runs before it. - A first backup that fails earlier, on a missing bucket, a refused credential or missing recipients, leaves the index unbound. Correcting the config and running again works. - Other commands that bind the index keep their current order unless they bind before their own first write. If so, apply the same rule and list them in the PR body. - Tests: a first backup to a destination that refuses every request, then a backup to a working one with the same index, succeeds. Package: `internal/vaultik`. **For every unit from the acceptance test** - One branch off current `next`, one PR with base `next`, labelled `needs-review` and assigned to `clawbot`. The title ends `(closes #N)`. - Add nothing to `docs/TODO.md`. sneak ruled on 11 November that it is not a history document (https://git.eeqj.de/sneak/vaultik/issues/440). - `README.md` on `next`: change only a sentence the fix makes false. The rewritten README in https://git.eeqj.de/sneak/vaultik/pulls/399 is with sneak and is updated after this merges. - A test that fails on current `next` shows the fix. Run `make fmt` and `make check` before the final push. Model: opus-5-5
clawbot self-assigned this 2026-11-11 01:12:25 +01:00
Author
Collaborator

Built in #445.

  • A backup binds the local index only after it has written vaultik-destination.txt to the destination. A first backup that fails earlier leaves the index unbound.
  • Judgement call: snapshot purge, prune, snapshot remove and remote nuke all bound before their first write. They now only refuse a different binding and never record one. Only a backup puts data in the local index, so an unbound index holds nothing to protect.
  • The README sentence in #399 ("The first command that changes data saves the configured destination") should name the first backup instead.

Model: opus-5-5

Built in https://git.eeqj.de/sneak/vaultik/pulls/445. - A backup binds the local index only after it has written `vaultik-destination.txt` to the destination. A first backup that fails earlier leaves the index unbound. - Judgement call: `snapshot purge`, `prune`, `snapshot remove` and `remote nuke` all bound before their first write. They now only refuse a different binding and never record one. Only a backup puts data in the local index, so an unbound index holds nothing to protect. - The README sentence in https://git.eeqj.de/sneak/vaultik/pulls/399 ("The first command that changes data saves the configured destination") should name the first backup instead. Model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/vaultik#420