Relationships
#3806 When the vault behind a stored sensitive-field reference cannot be read, swamp reports 'Refusing to evaluate expression … arrived as data content' instead of the vault error
Opened by dmc · 10/23/2026· Shipped 10/23/2026
Description
When the vault that holds a stored sensitive-field value cannot be read, swamp does not report the vault failure. It reports that the stored ${{ vault.get(...) }} reference is untrusted text ("Refusing to evaluate expression … arrived as data content") and then fails with "Unresolved expression". The real cause is not logged, even at --log-level debug.
Steps to reproduce
swamp 20261022.161828.0-sha.3cef43ef, macOS (Apple silicon).
- A behavior with sensitive outputs stores them in a
@swamp/1passwordvault. Here@keeb/proxmox/nodeauth(2026.07.18.1) withdefaultVault: infra, so its data holdsticket: ${{ vault.get('infra', 'keeb-proxmox-node-…-auth-node-node-ticket') }}(tagged_swamp.sensitiveFields). - Another behavior reads it in its global arguments, as written in the definition:
ticket: ${{ data.latest("proxmox-node", "node").attributes.ticket }}(@keeb/proxmox/vm). - Control: with
opworking,swamp behavior run swamp-serve-vm getConfig --input vmName=swamp-servesucceeds. - Make the vault unreadable and run the same method:
- remove
opfromPATH(it lives in/opt/homebrew/bin), or - let the 1Password desktop-app approval time out (the original incident).
- remove
Actual
[WRN] swamp·expressions: Refusing to evaluate expression at "globalArguments.ticket": it was not written in the definition or workflow source, so it arrived as data content. Left as literal text. Raw: "${{ vault.get('infra', 'keeb-proxmox-node-…-ticket') }}"
[WRN] swamp·expressions: Refusing to evaluate expression at "globalArguments.csrfToken": …
Error: Unresolved expression in globalArguments.ticket (contains a vault.get() or env reference that was not resolved — expression syntax arriving as data content is left as literal text and never evaluated; …)With --log-level debug there is still no line about the infra vault, op, or the read failure.
Expected
The error names the failed vault read: the vault (infra), the key, and the provider's error (for example op not found, or 1Password authentication failed … authorization timeout). The "arrived as data content" warning should not fire for a reference swamp itself wrote as a sensitive-field value when the real problem is that the vault could not be read.
Impact
The message points at expression trust, so the real cause is hidden. We spent time on a wrong hypothesis (that references written by workflow steps were refused), and only isolated it by removing op from PATH.
Related: Lab #3805 (why the reference pointed at a 1Password vault in the first place).
Shipped
Click a lifecycle step above to view its details.
zack commented 10/23/2026, 1:27:10 AM
Thanks @dmc for reporting this! We shipped: Stop discarding vault errors when a stored sensitive-field reference cannot be read. resolveSensitiveVaultRefs resolves each tagged field independently and records each failed read (vault, key, field, provider error) on the run's RunSensitiveValues, keeping the legacy rule of leaving the reference text in place. The refusal warning is replaced by a warning naming the failed vault read when the refused text is a reference swamp itself tried to read. The lazy globalArgs proxy error names the vault, key and provider error, and a method argument holding such a reference fails delivery with the same error. Methods that never read a global field still succeed.. The fix has been merged and a release is on its way. We appreciate your contribution to swamp.
Sign in to post a ripple.