Skip to content
DeviceRent
FleetDeviceyAIHow it worksPricingCommunity
Log inOpen app
All posts

September 2, 2026

The phone that couldn't be cleaned: a dead end nobody could see

A phone can be marked available and still owe a wipe. When both were true at once it became unrentable and unwipeable at the same time — and nothing was watching for it.

One of our six phones spent over six hours this week in a state that, on paper, should not exist: it was available — rentable, listed in the catalog — and it was flagged wipe_required — meaning the rent gate would refuse anyone who tried to rent it. Available and un-rentable. Also, as it turned out, un-wipeable. It was stuck, and nothing in the system was going to unstick it on its own.

This is the story of how it got there, why nothing noticed, and the anticlimactic way it fixed itself the moment we stopped looking at the wrong door.

A flag designed to outlive its neighbor

wipe_required exists on purpose as something that can be true even after status has moved on. The idea: a phone finishes a rental, gets parked back into available while the wipe queue picks it up in the background, and only the rent gate needs to know it's still dirty. Customers shouldn't see "sanitizing" for a wipe that takes four seconds; they should just never be handed a phone that hasn't been cleaned.

That's a reasonable design. The trap was that four different functions across the codebase had each independently decided the honest way to answer "does this phone still owe a wipe?" was to read status, not the flag built for exactly that question. A new source of truth is only true in the places that were actually updated to read it. Everywhere else, it's still lying, just less obviously.

How it got in

The entrance was almost polite. An admin flipped a phone from maintenance to available — a completely reasonable action, done in good faith — and 284 milliseconds later the Pi sent its next wipe-failure report for that same device. That report no-op'd, silently, because the handler that processes it only fires when status = 'sanitizing'. The phone was already available by then. Nothing told the admin the flag hadn't cleared. As far as anyone looking at a screen could tell, the wipe had finished normally.

There was a second way in that needed no admin at all: report_device_presence — the function that fires when a phone reconnects — promoted offline straight to available without ever checking wipe_required. Unplug the USB cable and plug it back in, and you'd land in the identical trap. No human required, no audit trail to follow.

Why it never healed

Here's the part that actually kept it stuck. The wipe queue's own query was:

sanitizing OR (maintenance AND wipe_required)

An available phone with wipe_required = true matches neither branch. It wasn't being actively sanitized, and it wasn't in maintenance. So it simply fell out of the queue. The Pi never asked about it again — not because it was broken, but because nothing was offering it the phone anymore. A wipe that never gets attempted can't fail, and it can't succeed either. It just sits.

The twist

Once we understood the shape of the trap, the obvious fix was to make the flag itself the thing the queue keys on, not a combination of columns that could silently stop matching. We half-expected the phone would also need someone physically at the rack — an earlier read of this incident assumed the screen lock left over from the last renter would need a human to clear it.

It didn't. The instant the queue fix went live, the Pi was offered that phone for the first time in over six hours, and the wipe just worked — seven renter files removed, done in under three seconds. The lock had already cleared itself ages ago. The phone hadn't been waiting for a fix. It had been waiting for someone to check on it again, and nothing ever had.

The lesson underneath that is worth sitting with: a "this needs hardware intervention" verdict has a shelf life. Re-test before you accept it, because the ground it was standing on can move while you're not looking.

The retry storm we didn't know we'd been running

Fixing the dead end surfaced something less charming. It turned out the trap had been the only thing capping retries. A phone that's maintenance and flagged is deliberately still in the queue — that's correct — but with no dead end to eventually fall into, the agent had been hammering that state at one attempt per eight-second poll. Before this phone dropped into the trap, it logged 387 failed wipe attempts in 53 minutes. That's 387 of the 469 total rows in the entire wipe-attempt history table, from one phone, in less than an hour.

So the real fix isn't just "join the queue correctly" — it's also a cooldown: 30 seconds, doubling up to 15 minutes, scaled by how many failures have piled up since the last success. A phone that wipes cleanly every time is never delayed. A phone that's actually stuck stops drowning the log instead of quietly becoming the majority of it.

What actually shipped

The dead end closes with a queue predicate that keys on the flag, not a status combination that can drift out of sync with it. The retry storm closes with a real backoff, applied on the database side so it holds regardless of which version of the wipe agent happens to be running on the Pi that week. And there's now a step-up-gated admin action to clear the flag by hand, for the day this happens again and nobody wants to wait for a queue fix to deploy.

Six phones, zero flagged, and one very small database query that now means what it says.

All posts
DeviceRent
PricingDeviceyAILog inSign upCommunityBlogFeedbackTermsPrivacyCookiesDevices hosted in the Netherlands · EU© 2026 DeviceRent