← All posts

June 14 — a dependency cascade, and matching files back to a list

Two unrelated things ate this day: a system service that wouldn't start because I'd removed something it secretly depended on, and a file-matching bug that came down to trusting the wrong field.

The dependency cascade

The web admin UI on my storage box half-broke: the file browser reported "no shared folder available," and the user editor wouldn't load. Crucially, the underlying file serving and remote shell never stopped working — the data was never at risk. The breakage was confined to the management layer, which is exactly the kind of split that sends you hunting in the wrong place.

The chase went like this. A core system service was failing to start because its notification helper exited immediately, unable to load a shared library. That library was a symlink into a package I had uninstalled during an earlier cleanup — a remote-access feature I thought I didn't need. So: I removed a package → dangled a shared library → an unrelated core service couldn't start → the file browser and user editor broke. A classic load-bearing transitive dependency that nothing advertised.

The fix was almost anticlimactic: reinstall the package purely for its library, leave the feature itself switched off. The service started, the UI came back.

The more useful part was the audit afterward — "is anything else silently broken?" The service manager listed several "failed" units, and most of them were nothing:

The lesson: read the exit code before you believe the word "failed." One genuinely recurring crash turned out to predate the cleanup entirely and to be cosmetic. If I'd reacted to the red text instead of the exit codes, I'd have "fixed" four things that weren't broken.

Matching files back to a list

The other thread: I had a hand-curated list of ~150 large videos to stage, and I needed to match each row back to its real file in the database. The first pass matched all but four.

The culprit was my own filename normalizer. The ingest process appends a -<number> suffix to disambiguate names, so I was stripping a trailing -<digits> group before matching. But some real filenames legitimately end in -<digits> (a date like ...-2, a camera serial, a literal numeric ID). Stripping blindly mangled them.

The fix is a nice little invariant: only strip the trailing -<digits> when those digits exactly equal that file's byte size — because that's the only case where the suffix is actually the size-disambiguator and not part of the real name. With that, the match went to 150/150, every one a distinct file, every one byte-exact on size.

That surfaced the deeper rule: byte-exact file size plus filename stem is the reliable join key; capture timestamps are not. A good chunk of the matches showed a divergent capture timestamp — the photo app and my extraction disagree on timezone — yet the size and stem agreed perfectly. Size doesn't drift. Timestamps do.

Decisions

Learned