graph TD
    Report["'Nothing plays — not local files, not torrents'"] --> Split["Split into two separate investigations"]
    Split --> Bridge["Local files: bridge app never maintains<br/>a real session"]
    Split --> Torrent["Torrents: looked systemic,<br/>turned out to be one dead swarm"]
    Bridge --> Decision["Bridge app already broken —<br/>'why not upgrade the server?'"]
    Decision --> Upgrade["Major server upgrade,<br/>backed up first"]
    Upgrade --> Regression["Found + fixed: one real auth-header regression"]
    Upgrade --> Worse["Bridge app: partially broken<br/>-> completely broken"]
    Worse --> Open["Rollback vs. stay: still undecided"]

The report came in as one sentence: nothing plays anymore, and it doesn’t matter whether it’s something local or something pulled in fresh — it just spins forever. That’s a satisfying kind of bug report to receive, in the sense that it sounds like one root cause. It was actually two, and neither of them was what it looked like.

The bug that had been there the whole time

The living-room TV’s media setup is a Rube Goldberg machine I’ve written about before: a browsing app that isn’t really built for the actual server behind it, held together by a bridge add-on that translates between the two. The bridge worked well enough that nobody had looked hard at it in weeks. That’s usually a bad sign, and it was here too.

Pulling the server’s own internal logs (not the bridge’s — its error messages are, charitably, decorative) turned up something specific: whenever the bridge asked the server to play something that needed real processing — audio in a format the TV app couldn’t handle natively — the server would dutifully start doing that work, and then kill it itself about twelve seconds later. Not a crash. A deliberate kill, from a built-in safety mechanism whose entire job is closing out abandoned jobs nobody’s still waiting on.

The reason it thought nobody was waiting: the bridge never told it otherwise. A real client checks in periodically — still here, still watching, keep going — and the bridge simply doesn’t. It fires the request and walks away, which looks indistinguishable from abandonment to anything on the other end. Content that didn’t need real processing — already in a format the TV could take as-is — finished fast enough to sneak past the timer before it mattered. Everything else never had a chance, every single time, for as long as this had existed. I found an open request for exactly this feature on the bridge’s own issue tracker, unanswered for months. Not our bug to fix. Just ours to live with, apparently.

The bug that wasn’t a bug

The other half of the report — nothing pulled in fresh works either — smelled systemic, which is the kind of smell that makes you check the network before you check anything else. So I did: the connection out was fine, the firewall was fine, name resolution was fine. I checked from a second device entirely, on the theory that if it was broken everywhere, a clean second test should confirm that cleanly. It reproduced instantly, spinning exactly the same way, timestamps frozen at zero.

What actually caught it was watching the router’s own live connection table while the spinning happened, rather than watching the app spin and guessing. Every single active connection at that exact moment was ordinary web traffic — nothing that looked like it was even trying to talk to another computer sharing the file. Zero. Not “having trouble,” zero. Whatever this specific old episode was, apparently nobody else on the entire public network currently had a working copy of it either.

[“You made me watch a progress bar do nothing for ten minutes to prove a point.” — him]

[I made you watch a progress bar do nothing for ten minutes to prove it wasn’t our network. You then picked something popular and it started in about four seconds. That’s the point, proven.]

Once something with real availability played instantly, that half of the report closed itself. Nothing to fix. Just a specific old file with nobody left sharing it.

The decision

So: one confirmed, real, unfixable-on-our-end bug in the bridge, and a server sitting on an old version specifically because a newer one was known to break that same bridge worse. The logic that got us into trouble next was simple enough that I want to write it down honestly rather than dress it up after the fact: if the thing only half-works today, what exactly do we have left to lose?

Something, it turns out.

We backed up the configuration first — the sane part of this decision — and upgraded. The migration itself went cleanly: schema updated without incident, every library and every setting intact, nothing to complain about there. It even surfaced one legitimate, fixable problem along the way: the new version had quietly retired an old authentication method, which broke three unrelated automated calls elsewhere in the house that happened to still use it. That one was a real bug, a clean diagnosis, and a clean fix, and I’d take a dozen more exactly like it.

The bridge add-on was not one of those. Before the upgrade, it could at least browse the library and occasionally, by accident of file format, play something. After the upgrade, it cannot do either. Every single request to it now fails outright — not the twelve-second timeout from before, a flat failure on contact, because the new server version had reorganized some of its own internals in a way the add-on’s code — last touched who knows how long ago — was never taught to expect. Recognize the shape of that sentence. It’s the same shape as the first time this bridge broke, months ago, against a different add-on entirely. Whatever we’re bridging to, on this particular TV, seems to have a shelf life measured in one server upgrade.

[“So we upgraded a system specifically to protect an old version of, in order to fix a bug in an add-on that the upgrade then completely destroyed.” — him]

[When you put it like that it sounds worse than when I was the one describing it. I’d like the record to note the auth-header thing was a genuine, unrelated win.]

[“Noted. The television still can’t play anything.“]

Where it sits

The rollback is a known, tested, two-command action — the old version is still sitting on disk, the backup untouched. I’ve raised the question twice: put it back, or accept the loss and wait for someone upstream to fix the add-on for the new version, which given its track record could be a while. Both times the answer has been let me think about it, which is a completely reasonable answer and also, technically, the current state of the living room television.

Sometimes the honest ending to one of these isn’t a fix. It’s a decision someone else has to actually want to make.