A cross-vault secret mv whose source could not be removed reports "Moved" and exits 0, leaving the secret in both vaults #159

Closed
opened 2026-10-13 00:39:06 +02:00 by clawbot · 1 comment
Collaborator

Severity: minor
A script cannot tell that the source is still there; nothing is lost, and removing the source by hand finishes the move.

What happens: moveSecretCrossVault copies every version into the destination vault, then removes the source; if that removal fails it prints a warning and the normal "Moved ..." line and returns nil, so the exit status is 0.

Reproduction (vaults default and work, source vault directory made read-only so the rename into a temporary directory fails):

echo v | secret add stuck
chmod 500 "$SB_SECRET_STATE_DIR/vaults.d/default"
secret mv default:stuck work; echo $?
# Warning: copied secret but failed to remove source: failed to create temporary directory for .../default/secrets.d/stuck: mkdir .../default/.tmp-...: permission denied
# Moved secret 'default:stuck' to 'work:stuck' (1 version(s))
# 0
chmod 700 "$SB_SECRET_STATE_DIR/vaults.d/default"
secret list -q                    # stuck   (still in default)

Where:

err = secret.RemoveDirAtomic(cli.fs, srcSecretDir)
(moveSecretCrossVault).

Correct behaviour: the command returns the removal error (exit 1) and says that the copy in the destination vault is complete and the source remains, so the user removes it with secret rm after checking; the README's "The source secret is deleted after successful copy" then holds or the command says it did not.

Definition of done

  • A cross-vault move whose source removal fails exits 1 with an error that names both the complete copy and the remaining source.
  • A test with a filesystem that fails the source removal requires a non-nil error and both copies present; it fails before the fix.

Model: fable-5-1

Severity: minor A script cannot tell that the source is still there; nothing is lost, and removing the source by hand finishes the move. What happens: `moveSecretCrossVault` copies every version into the destination vault, then removes the source; if that removal fails it prints a warning and the normal "Moved ..." line and returns nil, so the exit status is 0. Reproduction (vaults `default` and `work`, source vault directory made read-only so the rename into a temporary directory fails): ``` echo v | secret add stuck chmod 500 "$SB_SECRET_STATE_DIR/vaults.d/default" secret mv default:stuck work; echo $? # Warning: copied secret but failed to remove source: failed to create temporary directory for .../default/secrets.d/stuck: mkdir .../default/.tmp-...: permission denied # Moved secret 'default:stuck' to 'work:stuck' (1 version(s)) # 0 chmod 700 "$SB_SECRET_STATE_DIR/vaults.d/default" secret list -q # stuck (still in default) ``` Where: https://git.eeqj.de/sneak/secret/src/commit/ef0ae90768c8b18a829033b3ebd4cf98fcaeb3d1/internal/cli/secrets.go#L1068 (`moveSecretCrossVault`). Correct behaviour: the command returns the removal error (exit 1) and says that the copy in the destination vault is complete and the source remains, so the user removes it with `secret rm` after checking; the README's "The source secret is deleted after successful copy" then holds or the command says it did not. **Definition of done** - A cross-vault move whose source removal fails exits 1 with an error that names both the complete copy and the remaining source. - A test with a filesystem that fails the source removal requires a non-nil error and both copies present; it fails before the fix. Model: fable-5-1
sneak was assigned by clawbot 2026-10-13 00:39:06 +02:00
Author
Collaborator

Reassigned to clawbot: sneak ruled that nothing is a release candidate while a known bug is open (sneak/project-management#32).

Plan: as the issue says: when the source cannot be removed, the command exits 1 with an error saying the copy in the destination is complete and the source remains.

Model: opus-5-5

Reassigned to clawbot: sneak ruled that nothing is a release candidate while a known bug is open (https://git.eeqj.de/sneak/project-management/issues/32). Plan: as the issue says: when the source cannot be removed, the command exits 1 with an error saying the copy in the destination is complete and the source remains. Model: opus-5-5
sneak was unassigned by clawbot 2026-10-14 19:43:03 +02:00
clawbot self-assigned this 2026-10-14 19:43:03 +02:00
clawbot added this to the 1.0.0 milestone 2026-10-14 19:43:03 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/secret#159