What is wrong: transactions are bound to the run's context. On cancel, database/sql rolls the transaction back itself, so the explicit Rollback returns sql.ErrTxDone; WithTx (internal/database/repositories.go) treats any rollback error as fatal and calls os.Exit(1). The user gets a message that suggests damage to the local index, exit 1 instead of 130 ("interrupted before the command finished"), and deferred cleanup is skipped.
How it was shown: 8000 empty files, one backup, then 6 runs each sent SIGINT as soon as "Associating ... unchanged files" printed: all 6 exited 1 with FATAL: failed to rollback transaction: sql: transaction has already been committed or rolled back.
Definition of done
A rollback that finds the transaction already rolled back (sql.ErrTxDone) is not an error: WithTx returns the body's error, and an interrupted backup ends with the documented interrupted exit and message.
No path in WithTx exits the process; a real rollback failure is returned as an error.
A test covers a transaction whose context is cancelled during the body.
Model: opus-5-5
Found by the defect hunt in https://git.eeqj.de/sneak/vaultik/issues/288 (part 2).
**What is wrong:** transactions are bound to the run's context. On cancel, `database/sql` rolls the transaction back itself, so the explicit `Rollback` returns `sql.ErrTxDone`; `WithTx` (`internal/database/repositories.go`) treats any rollback error as fatal and calls `os.Exit(1)`. The user gets a message that suggests damage to the local index, exit 1 instead of 130 ("interrupted before the command finished"), and deferred cleanup is skipped.
**How it was shown:** 8000 empty files, one backup, then 6 runs each sent SIGINT as soon as "Associating ... unchanged files" printed: all 6 exited 1 with `FATAL: failed to rollback transaction: sql: transaction has already been committed or rolled back`.
**Definition of done**
- A rollback that finds the transaction already rolled back (`sql.ErrTxDone`) is not an error: `WithTx` returns the body's error, and an interrupted backup ends with the documented interrupted exit and message.
- No path in `WithTx` exits the process; a real rollback failure is returned as an error.
- A test covers a transaction whose context is cancelled during the body.
Model: opus-5-5
clawbot
self-assigned this 2026-10-13 00:47:09 +02:00
Implemented in #343: WithTx no longer treats the rollback that database/sql has already done after a cancel as a failure, and no longer ends the process on a rollback error, so an interrupted backup ends with the interrupted exit and message.
Model: opus-5-5
Implemented in https://git.eeqj.de/sneak/vaultik/pulls/343: `WithTx` no longer treats the rollback that `database/sql` has already done after a cancel as a failure, and no longer ends the process on a rollback error, so an interrupted backup ends with the interrupted exit and message.
Model: opus-5-5
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.
Found by the defect hunt in #288 (part 2).
What is wrong: transactions are bound to the run's context. On cancel,
database/sqlrolls the transaction back itself, so the explicitRollbackreturnssql.ErrTxDone;WithTx(internal/database/repositories.go) treats any rollback error as fatal and callsos.Exit(1). The user gets a message that suggests damage to the local index, exit 1 instead of 130 ("interrupted before the command finished"), and deferred cleanup is skipped.How it was shown: 8000 empty files, one backup, then 6 runs each sent SIGINT as soon as "Associating ... unchanged files" printed: all 6 exited 1 with
FATAL: failed to rollback transaction: sql: transaction has already been committed or rolled back.Definition of done
sql.ErrTxDone) is not an error:WithTxreturns the body's error, and an interrupted backup ends with the documented interrupted exit and message.WithTxexits the process; a real rollback failure is returned as an error.Model: opus-5-5
Implemented in #343:
WithTxno longer treats the rollback thatdatabase/sqlhas already done after a cancel as a failure, and no longer ends the process on a rollback error, so an interrupted backup ends with the interrupted exit and message.Model: opus-5-5