Severity: major
After secret unlocker remove removes the vault's current unlocker, every command that opens the vault fails although another working unlocker remains, and the error sends the user to the mnemonic instead of to secret unlocker select. Nothing is lost; unlocker select <other-id> repairs it.
What happens: RemoveUnlocker deletes the unlocker's directory and leaves current-unlocker naming it. GetCurrentUnlocker then fails on the missing metadata file, and withMnemonicAdvice adds "the vault still opens with its mnemonic: run 'secret unlocker add passphrase' ...". That advice is wrong here: unlocker add passphrase without the mnemonic fails the same way, and the vault needs no new unlocker. secret vault remove of the current vault switches to another vault first; removing the current unlocker does nothing of the kind. The confirmation says only "It is not the vault's last unlocker."
Reproduction (a throwaway GPG key in a fresh GNUPGHOME):
SB_UNLOCK_PASSPHRASE=pw SB_SECRET_MNEMONIC="$M" secret init
echo -n hunter2 | SB_UNLOCK_PASSPHRASE=pw secret add foo
SB_UNLOCK_PASSPHRASE=pw secret unlocker add pgp --keyid "$FPR" # becomes current
secret unlocker remove --force "$PGPID" # succeeds
SB_UNLOCK_PASSPHRASE=pw secret get foo
# Error: ... failed to get current unlocker: failed to read unlocker metadata: open .../unlockers.d/$PGPID/unlocker-metadata.json: no such file or directory; the vault 'default' still opens with its mnemonic: run 'secret unlocker add passphrase' ...
cat .../vaults.d/default/current-unlocker # still $PGPID
Correct behaviour is a product decision the README does not settle. Recommended: when the removed unlocker is current and another unlocker remains, make that one current in the same command (as vault remove does for vaults) and say so; when none remains, clear current-unlocker. In any case the error for a current-unlocker naming a missing directory should name secret unlocker select when other unlockers exist.
Definition of done
Removing the current unlocker leaves the vault openable through a remaining unlocker without a further command, or the error after it names secret unlocker select.
A regression test removes the current of two unlockers and requires GetOrDeriveLongTermKey to succeed through the other; it fails before the fix.
Model: fable-5-1
Severity: major
After `secret unlocker remove` removes the vault's current unlocker, every command that opens the vault fails although another working unlocker remains, and the error sends the user to the mnemonic instead of to `secret unlocker select`. Nothing is lost; `unlocker select <other-id>` repairs it.
What happens: `RemoveUnlocker` deletes the unlocker's directory and leaves `current-unlocker` naming it. `GetCurrentUnlocker` then fails on the missing metadata file, and `withMnemonicAdvice` adds "the vault still opens with its mnemonic: run 'secret unlocker add passphrase' ...". That advice is wrong here: `unlocker add passphrase` without the mnemonic fails the same way, and the vault needs no new unlocker. `secret vault remove` of the current vault switches to another vault first; removing the current unlocker does nothing of the kind. The confirmation says only "It is not the vault's last unlocker."
Reproduction (a throwaway GPG key in a fresh `GNUPGHOME`):
```
SB_UNLOCK_PASSPHRASE=pw SB_SECRET_MNEMONIC="$M" secret init
echo -n hunter2 | SB_UNLOCK_PASSPHRASE=pw secret add foo
SB_UNLOCK_PASSPHRASE=pw secret unlocker add pgp --keyid "$FPR" # becomes current
secret unlocker remove --force "$PGPID" # succeeds
SB_UNLOCK_PASSPHRASE=pw secret get foo
# Error: ... failed to get current unlocker: failed to read unlocker metadata: open .../unlockers.d/$PGPID/unlocker-metadata.json: no such file or directory; the vault 'default' still opens with its mnemonic: run 'secret unlocker add passphrase' ...
cat .../vaults.d/default/current-unlocker # still $PGPID
```
Where: https://git.eeqj.de/sneak/secret/src/commit/ef0ae90768c8b18a829033b3ebd4cf98fcaeb3d1/internal/vault/unlockers.go#L299 (`RemoveUnlocker`), https://git.eeqj.de/sneak/secret/src/commit/ef0ae90768c8b18a829033b3ebd4cf98fcaeb3d1/internal/cli/unlockers.go#L705 (`removeUnlocker`), https://git.eeqj.de/sneak/secret/src/commit/ef0ae90768c8b18a829033b3ebd4cf98fcaeb3d1/internal/vault/vault.go#L309 (`withMnemonicAdvice`).
Correct behaviour is a product decision the README does not settle. Recommended: when the removed unlocker is current and another unlocker remains, make that one current in the same command (as `vault remove` does for vaults) and say so; when none remains, clear `current-unlocker`. In any case the error for a `current-unlocker` naming a missing directory should name `secret unlocker select` when other unlockers exist.
**Definition of done**
- Removing the current unlocker leaves the vault openable through a remaining unlocker without a further command, or the error after it names `secret unlocker select`.
- A regression test removes the current of two unlockers and requires `GetOrDeriveLongTermKey` to succeed through the other; it fails before the fix.
Model: fable-5-1
sneak
was assigned by clawbot2026-10-13 00:29:59 +02:00
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.
Severity: major
After
secret unlocker removeremoves the vault's current unlocker, every command that opens the vault fails although another working unlocker remains, and the error sends the user to the mnemonic instead of tosecret unlocker select. Nothing is lost;unlocker select <other-id>repairs it.What happens:
RemoveUnlockerdeletes the unlocker's directory and leavescurrent-unlockernaming it.GetCurrentUnlockerthen fails on the missing metadata file, andwithMnemonicAdviceadds "the vault still opens with its mnemonic: run 'secret unlocker add passphrase' ...". That advice is wrong here:unlocker add passphrasewithout the mnemonic fails the same way, and the vault needs no new unlocker.secret vault removeof the current vault switches to another vault first; removing the current unlocker does nothing of the kind. The confirmation says only "It is not the vault's last unlocker."Reproduction (a throwaway GPG key in a fresh
GNUPGHOME):Where:
RemoveUnlocker),removeUnlocker),withMnemonicAdvice).Correct behaviour is a product decision the README does not settle. Recommended: when the removed unlocker is current and another unlocker remains, make that one current in the same command (as
vault removedoes for vaults) and say so; when none remains, clearcurrent-unlocker. In any case the error for acurrent-unlockernaming a missing directory should namesecret unlocker selectwhen other unlockers exist.Definition of done
secret unlocker select.GetOrDeriveLongTermKeyto succeed through the other; it fails before the fix.Model: fable-5-1