The invisible shells: $600 stuck idle behind zero-liquidity NFTs
≈ $600
Capital stuck idle
days, silent
Duration
inline burn + retry
Fix
TL;DR
On Solana CLMMs, closing out a position's liquidity does not necessarily remove its position NFT. Our vault held "shell" positions — zero liquidity, NFT still on-chain — and the invest path refused to open a fresh position where one existed, throwing an error that told the operator to click a manual admin button. The autonomy loop has no operator. Every hourly tick, investments failed; divestments kept succeeding. The fix made the failure path self-healing.
What happened
A live vault sat with about $600 in idle cash for days and never redeployed it, while its analysis logs showed perfectly good investment plans being generated every hour — pools selected, amounts sized, expected net benefit computed and passing every floor.
The execution logs told a different story: every invest action ended in the same failure. Earlier allocation churn had wound two positions down to zero liquidity, but their position NFTs and on-chain accounts remained. Our invest path treats an existing position account at a pool as "you already have a position here" and refuses to open a fresh one — by design, to avoid stacking duplicates. The error message it threw was written for a human: it named the manual "Burn Closed NFTs" button in the admin dashboard.
The autonomy loop has no human in it. So the plan generator kept proposing the same sensible invests, the executor kept hitting the same shell, and the vault earned nothing on a third of its capital. Meanwhile divests kept working fine — the one-way valve pointed the wrong way.
What it was not
Half the diagnostic work was ruling out the plausible suspects: funding (the vault had an ample SOL budget), the minimum net-benefit floor (the queued invests cleared it with margin), stale APR data, and scoring (the target pool scored high and deserved the allocation). The plan was right. Only the last inch of execution was broken — which is exactly why it stayed invisible: everything upstream reported success.
The fix
The executor's invest handler now catches the shell-position error, burns the zero-liquidity NFTs inline (zero liquidity means zero funds at risk in the burn), and retries the open once. The manual admin button still exists, but the autonomous path no longer depends on anyone clicking it.
The burn routine itself already existed and worked — it had simply only ever been wired to a human-triggered button and an observe-only reconciler. The gap was never capability; it was that an error path terminated in an instruction to a human who was not there.
What we took away
In an autonomous system, an error message that instructs a human is a dead end. Every failure path must either self-heal or page someone.
Watch for one-way valves: sells succeeding while buys silently fail drains a vault into idle cash without a single alert.
Success upstream (planning, scoring, sizing) can mask failure at the last step. Judge the pipeline by executed outcomes, not by generated plans.
This case study describes an engineering incident on a small live test vault, published for transparency and education. It is not financial advice. See all case studies or the live signal track record.




