Previously, deleteSnapshotFromLocalDB logged errors but always returned nil,
causing callers to believe deletion succeeded even when it failed. This could
lead to data inconsistency where remote metadata is deleted while local
records persist.
Now returns the first error encountered, allowing callers to handle failures
appropriately.
Review: Return errors from deleteSnapshotFromLocalDB instead of swallowing them
Positives:
Clear, correct fix. Swallowing errors in a delete cascade is a real bug — callers had no way to know the DB was left in an inconsistent state.
Error messages use consistent "deleting X for %s: %w" format with %w wrapping. Clean.
Minimal, focused diff.
Concerns:
Partial deletion on early return — If DeleteSnapshotFiles succeeds but DeleteSnapshotBlobs fails, you've now deleted files but left blobs and the snapshot record behind. The old code at least attempted all four deletes regardless of individual failures. Consider wrapping all errors and returning them together (e.g. errors.Join), or using a transaction so the whole thing is atomic. At minimum, document that callers should be aware of partial state.
Callers may not handle the new errors — Previously this function effectively never failed from the caller's perspective. Check that all call sites handle the returned error appropriately (log it, surface it to the user, retry, etc.).
Despite the partial-delete concern, returning errors is strictly better than silently swallowing them. The partial-delete issue existed before too (just hidden). Ship it, and consider the transaction/multi-error approach as a follow-up.
## Review: Return errors from deleteSnapshotFromLocalDB instead of swallowing them
**Positives:**
- Clear, correct fix. Swallowing errors in a delete cascade is a real bug — callers had no way to know the DB was left in an inconsistent state.
- Error messages use consistent `"deleting X for %s: %w"` format with `%w` wrapping. Clean.
- Minimal, focused diff.
**Concerns:**
1. **Partial deletion on early return** — If `DeleteSnapshotFiles` succeeds but `DeleteSnapshotBlobs` fails, you've now deleted files but left blobs and the snapshot record behind. The old code at least attempted all four deletes regardless of individual failures. Consider wrapping all errors and returning them together (e.g. `errors.Join`), or using a transaction so the whole thing is atomic. At minimum, document that callers should be aware of partial state.
2. **Callers may not handle the new errors** — Previously this function effectively never failed from the caller's perspective. Check that all call sites handle the returned error appropriately (log it, surface it to the user, retry, etc.).
Despite the partial-delete concern, returning errors is strictly better than silently swallowing them. The partial-delete issue existed before too (just hidden). Ship it, and consider the transaction/multi-error approach as a follow-up.
Please confirm go vet, linting, and the full test suite pass. Additionally:
Are there tests covering the error-return paths? The behavior change (previously silent, now returns errors) could break callers that do not expect failures here. Unit tests exercising each failure branch would be expected for this kind of change.
**Blocker: No evidence of passing tests or linting.**
Please confirm `go vet`, linting, and the full test suite pass. Additionally:
- Are there tests covering the error-return paths? The behavior change (previously silent, now returns errors) could break callers that do not expect failures here. Unit tests exercising each failure branch would be expected for this kind of change.
Merge conflict markers found in internal/vaultik/snapshot.go (lines 1129-1150). go fmt and compilation both fail.
FAIL: Lint (golangci-lint)
New errors introduced by this PR (not on main):
prune.go:6: os imported and not used
prune.go:201: undefined: v
restore.go:22: golang.org/x/term imported and not used
restore.go:631: undefined: v / too many arguments in call to isTerminal
Pre-existing (also on main): 4x unused functions in io.go
PASS: go vet
Tests (go test ./...)
Most packages pass. One failure: TestBackupAndRestore (blob not found during restore, likely pre-existing).
Summary
This PR has merge conflict markers and compilation errors. Needs fixes in snapshot.go (conflict), prune.go (unused import, undefined var), and restore.go (unused import, undefined var).
## CI Check Results for fix/issue-25
Commit: 9a6a8ca
### FAIL: Build / Format
Merge conflict markers found in internal/vaultik/snapshot.go (lines 1129-1150). go fmt and compilation both fail.
### FAIL: Lint (golangci-lint)
New errors introduced by this PR (not on main):
- prune.go:6: os imported and not used
- prune.go:201: undefined: v
- restore.go:22: golang.org/x/term imported and not used
- restore.go:631: undefined: v / too many arguments in call to isTerminal
Pre-existing (also on main): 4x unused functions in io.go
### PASS: go vet
### Tests (go test ./...)
Most packages pass. One failure: TestBackupAndRestore (blob not found during restore, likely pre-existing).
### Summary
This PR has merge conflict markers and compilation errors. Needs fixes in snapshot.go (conflict), prune.go (unused import, undefined var), and restore.go (unused import, undefined var).
Correction: The previous CI check report was incorrect. The merge conflict markers and compilation errors were artifacts of a dirty local working directory (multiple sub-agents sharing the same clone). The actual branch (fix/issue-25, commit 9a6a8ca) on Gitea is clean — no conflict markers, merges cleanly into current main.
I will re-run the CI checks in a fresh, isolated clone and post corrected results.
**Correction:** The previous CI check report was incorrect. The merge conflict markers and compilation errors were artifacts of a dirty local working directory (multiple sub-agents sharing the same clone). The actual branch (`fix/issue-25`, commit 9a6a8ca) on Gitea is clean — no conflict markers, merges cleanly into current main.
I will re-run the CI checks in a fresh, isolated clone and post corrected results.
internal/vaultik/restore.go:478:19: v.FetchAndDecryptBlob undefined (type *Vaultik has no field or method FetchAndDecryptBlob)
internal/vaultik/verify.go:290:22: v.FetchBlob undefined (type *Vaultik has no field or method FetchBlob)
These methods are called on *Vaultik but not defined on the type. The PR needs to add these methods or update the call sites.
## CI Re-check Results (branch fix/issue-25)
### Build (go build ./...) - FAIL
internal/vaultik/restore.go:478:19: v.FetchAndDecryptBlob undefined (type *Vaultik has no field or method FetchAndDecryptBlob)
internal/vaultik/verify.go:290:22: v.FetchBlob undefined (type *Vaultik has no field or method FetchBlob)
### Vet (go vet ./...) - FAIL
Same compilation errors as above.
### Tests (go test ./...) - PARTIAL FAIL
Passing: blob, blobgen, chunker, config, crypto, database, globals, models, pidlock, s3, snapshot
Failing (build failed): cmd/vaultik, internal/cli, internal/vaultik
### Formatting (gofmt -l .) - PASS
No formatting issues.
### Summary
Two undefined methods block compilation:
- v.FetchAndDecryptBlob in restore.go:478
- v.FetchBlob in verify.go:290
These methods are called on *Vaultik but not defined on the type. The PR needs to add these methods or update the call sites.
Clean, straightforward fix. The change correctly converts silent error-swallowing (log.Error + continue) into proper error returns with fmt.Errorf and %w wrapping.
One consideration: The early-return pattern means that if DeleteSnapshotFiles fails, the snapshot record, blobs, and uploads remain — leaving partial state. The previous code (logging and continuing) would at least attempt all deletions. Whether this is desirable depends on whether callers retry or whether partial cleanup is worse than leaving orphaned child records. If the caller retries the whole operation, early-return is correct. If not, you might want to accumulate errors with errors.Join and attempt all four deletions regardless.
Otherwise the error messages are clear and consistent. Good to merge as-is if callers handle retry.
## Code Review
**Verdict: LGTM ✅**
Clean, straightforward fix. The change correctly converts silent error-swallowing (`log.Error` + continue) into proper error returns with `fmt.Errorf` and `%w` wrapping.
**One consideration:** The early-return pattern means that if `DeleteSnapshotFiles` fails, the snapshot record, blobs, and uploads remain — leaving partial state. The previous code (logging and continuing) would at least attempt all deletions. Whether this is desirable depends on whether callers retry or whether partial cleanup is worse than leaving orphaned child records. If the caller retries the whole operation, early-return is correct. If not, you might want to accumulate errors with `errors.Join` and attempt all four deletions regardless.
Otherwise the error messages are clear and consistent. Good to merge as-is if callers handle retry.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Review: Return errors from deleteSnapshotFromLocalDB instead of swallowing them
Positives:
"deleting X for %s: %w"format with%wwrapping. Clean.Concerns:
Partial deletion on early return — If
DeleteSnapshotFilessucceeds butDeleteSnapshotBlobsfails, you've now deleted files but left blobs and the snapshot record behind. The old code at least attempted all four deletes regardless of individual failures. Consider wrapping all errors and returning them together (e.g.errors.Join), or using a transaction so the whole thing is atomic. At minimum, document that callers should be aware of partial state.Callers may not handle the new errors — Previously this function effectively never failed from the caller's perspective. Check that all call sites handle the returned error appropriately (log it, surface it to the user, retry, etc.).
Despite the partial-delete concern, returning errors is strictly better than silently swallowing them. The partial-delete issue existed before too (just hidden). Ship it, and consider the transaction/multi-error approach as a follow-up.
Blocker: No evidence of passing tests or linting.
Please confirm
go vet, linting, and the full test suite pass. Additionally:@clawbot please run tests and linting checks per usual and comment with results here.
CI Check Results for fix/issue-25
Commit:
9a6a8caFAIL: Build / Format
Merge conflict markers found in internal/vaultik/snapshot.go (lines 1129-1150). go fmt and compilation both fail.
FAIL: Lint (golangci-lint)
New errors introduced by this PR (not on main):
Pre-existing (also on main): 4x unused functions in io.go
PASS: go vet
Tests (go test ./...)
Most packages pass. One failure: TestBackupAndRestore (blob not found during restore, likely pre-existing).
Summary
This PR has merge conflict markers and compilation errors. Needs fixes in snapshot.go (conflict), prune.go (unused import, undefined var), and restore.go (unused import, undefined var).
Correction: The previous CI check report was incorrect. The merge conflict markers and compilation errors were artifacts of a dirty local working directory (multiple sub-agents sharing the same clone). The actual branch (
fix/issue-25, commit9a6a8ca) on Gitea is clean — no conflict markers, merges cleanly into current main.I will re-run the CI checks in a fresh, isolated clone and post corrected results.
CI re-check test
CI Re-check Results (branch fix/issue-25)
Build (go build ./...) - FAIL
internal/vaultik/restore.go:478:19: v.FetchAndDecryptBlob undefined (type *Vaultik has no field or method FetchAndDecryptBlob)
internal/vaultik/verify.go:290:22: v.FetchBlob undefined (type *Vaultik has no field or method FetchBlob)
Vet (go vet ./...) - FAIL
Same compilation errors as above.
Tests (go test ./...) - PARTIAL FAIL
Passing: blob, blobgen, chunker, config, crypto, database, globals, models, pidlock, s3, snapshot
Failing (build failed): cmd/vaultik, internal/cli, internal/vaultik
Formatting (gofmt -l .) - PASS
No formatting issues.
Summary
Two undefined methods block compilation:
These methods are called on *Vaultik but not defined on the type. The PR needs to add these methods or update the call sites.
Code Review
Verdict: LGTM ✅
Clean, straightforward fix. The change correctly converts silent error-swallowing (
log.Error+ continue) into proper error returns withfmt.Errorfand%wwrapping.One consideration: The early-return pattern means that if
DeleteSnapshotFilesfails, the snapshot record, blobs, and uploads remain — leaving partial state. The previous code (logging and continuing) would at least attempt all deletions. Whether this is desirable depends on whether callers retry or whether partial cleanup is worse than leaving orphaned child records. If the caller retries the whole operation, early-return is correct. If not, you might want to accumulate errors witherrors.Joinand attempt all four deletions regardless.Otherwise the error messages are clear and consistent. Good to merge as-is if callers handle retry.
9a6a8caff9doddc23f8057make testpasses cleanly (no rebase needed):