zsh: verify opc/opd against the vault and explain failures

op item edit can exit non-zero with "(404) Not Found" after an edit it
did save (seen with op 2.34.1 and 2.39.0 on an existing item), which
made opc report failure and skip the ops refresh. opc now reads the
field back and opd re-checks the item's labels, then prints either the
op:// reference it changed or what failed, op's message without its
timestamp prefix, and where to look next.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-29 16:49:10 +00:00
co-authored by Claude Opus 5.5
parent 5f0dec5270
commit 41a90a10fb
+26 -3
View File
@@ -107,12 +107,35 @@ opc() {
[[ -n $value ]] || { print -u2 "opc: empty value for $name; nothing changed"; return 1; }
fi
# [concealed] makes it a password field; an existing field of that name is updated.
_dotfiles_op sh -c 'op item edit "$OP_ITEM" --vault "$OP_VAULT" "$1[concealed]=$2" >/dev/null' \
opc "$name" "$value" && ops
# op can exit non-zero with "(404) Not Found" after an edit it did save (seen with
# op 2.34.1 and 2.39.0), so its exit code is ignored: the field is read back instead.
_dotfiles_op sh -c '
clean() { printf "%s" "${1:-(no output)}" | sed "s/^\[ERROR\] [0-9/]* [0-9:]* //"; }
ref="op://$OP_VAULT/$OP_ITEM/$1"
err=$(op item edit "$OP_ITEM" --vault "$OP_VAULT" "$1[concealed]=$2" 2>&1 >/dev/null)
if [ "$(op read "$ref" 2>/dev/null)" = "$2" ]; then
printf "opc: saved %s\n" "$ref" >&2
else
printf "opc: could not save %s\n op said: %s\n check vault, item and service-account write access with: opl\n" \
"$ref" "$(clean "$err")" >&2
exit 1
fi' opc "$name" "$value" && ops
}
opd() {
_dotfiles_env_name "$1" opd || return
_dotfiles_op sh -c 'op item edit "$OP_ITEM" --vault "$OP_VAULT" "$1[delete]" >/dev/null' opd "$1" \
# As in opc, op's exit code is unreliable here: check the item's field labels instead.
_dotfiles_op sh -c '
clean() { printf "%s" "${1:-(no output)}" | sed "s/^\[ERROR\] [0-9/]* [0-9:]* //"; }
ref="op://$OP_VAULT/$OP_ITEM/$1"
err=$(op item edit "$OP_ITEM" --vault "$OP_VAULT" "$1[delete]" 2>&1 >/dev/null)
if ! item=$(op item get "$OP_ITEM" --vault "$OP_VAULT" --format json 2>&1); then
printf "opd: could not re-read %s to confirm the delete\n op said: %s\n" "$ref" "$(clean "$item")" >&2
exit 1
elif printf "%s" "$item" | jq -r ".fields[].label" | grep -qxF "$1"; then
printf "opd: could not delete %s\n op said: %s\n" "$ref" "$(clean "$err")" >&2
exit 1
fi
printf "opd: deleted %s\n" "$ref" >&2' opd "$1" \
&& unset "$1" && ops
}
opl() {