Wilhelm Maritz
  • Home
  • About
  • Skills
  • Projects
  • Posts
  • Dark Theme
    Light Theme Dark Theme System Theme
  • Posts
Hero Image
The scanner that was never broken

pacman -Qq | grep -iE 'sane|scan' returned exactly one package: hyprwayland-scanner, which is a Hyprland build tool and nothing to do with scanners. That was the whole diagnosis. The scan half of my HP OfficeJet Pro 8710 had never worked from this machine, I’d assumed that meant a driver I hadn’t installed, and the truth was that nothing at all had ever been installed to talk to it. The printer’s side had been ready the entire time. Its IPP record advertises Scan=T and mopria-certified=1.3, and http://192.168.1.3/eSCL/ScannerCapabilities answers 200 with eSCL 2.5, offering the flatbed, the document feeder, and duplex. It had been offering for as long as it had been on the network. Nobody was listening.

Sunday, August 30, 2026 | 5 minutes Read
Hero Image
The 144 Hz monitor that preferred 60

hyprctl monitors said [email protected]. hyprctl monitors all listed 143.86Hz, 119.88Hz and 69.92Hz as available on the same output. An HP 27xq on DisplayPort, a 144 Hz panel, running at 60 because that is what it had been asked for. This is the trap I owed a post to when I wrote about where the distro hopping stopped; it turned out to have two more acts. Here is the line that asked for it, as Omarchy shipped it in ~/.config/hypr/monitors.lua:

Friday, August 28, 2026 | 7 minutes Read
Hero Image
Where the distro hopping stopped

I’ve been distro hopping for a while now. Ubuntu first, because that’s where everyone starts. Zorin when I wanted it to look nicer. CachyOS when I wanted it to go faster. And now Omarchy. Two days in - the fastfetch below still shows an OS age you can count on one finger - and I’m calling it early: this is where the hopping stops. Wallpaper: Solace by thaomaoh

Monday, August 24, 2026 | 4 minutes Read
Hero Image
I wrote the lesson down. I broke it two days later.

My competition platform keeps a lessons-learned file. On 31 July I wrote a new entry into it: fix the shape, not the instance - when a bug is a pattern, hunt down every copy instead of patching the one that got reported. On 2 August the profile page went down for every athlete with an approved entry - a handful of people at that point, which is the only reason it wasn’t worse. Same bug class I’d fixed a week earlier on the leaderboard: a margin > 0 comparison with no guard, sitting in a second hand-written copy of the same formatting logic that nobody remembered existed.

Wednesday, August 5, 2026 | 5 minutes Read
Hero Image
My GitHub recovery codes lived on GitHub

Found github-recovery-codes.txt in my vault this weekend, in a folder called Important Docs. The vault is an Obsidian setup that auto-commits every ten minutes and pushes to a private GitHub repo. So the codes for getting back into GitHub were sitting behind the GitHub login. Think about the day I actually need them - phone gone, authenticator gone, sessions expired. Can’t clone the repo. Can’t open the site. The codes might as well not exist.

Sunday, August 2, 2026 | 3 minutes Read
Hero Image
OneDrive and git fought over my vault. Both lost.

Over two days my Obsidian vault appeared to delete itself, git recorded 146 file deletions that never happened, and OneDrive spawned 120 conflict copies of notes I had just restored. Not one byte of a note was lost. Every failure traces back to a single sentence: two sync systems each believed they owned the same tree, and each interpreted the other’s behaviour as changes to sync. I have written this shape of post before. RAID1 saved my data but not the state around it, and a trap I had published a warning about caught my own app the same day. This one belongs to both families: the data was never in danger, the state lied about it, and the limit that made it all worse was documented in a workbook I had read and dismissed as something that happens to other people.

Friday, July 31, 2026 | 7 minutes Read
Hero Image
Case study: the Paul Newman Cup

The Paul Newman Cup is an annual inter-team fitness and sports competition, and this app is the platform that runs it: scoring, verification, standings, and administration. It is small, deliberately so, and it is in production with real users. This page is the whole story in one place: what problem it solves, how it is built, what I decided and why, what I planned for going wrong, and what actually did.

Friday, July 24, 2026 | 6 minutes Read
Hero Image
Hugo's module.mounts quietly replaced my static directory

This site had a bug that survived several deploys unnoticed: the whole site worked, except that the OpenGraph card, the image that link previews show when you paste a URL into WhatsApp or LinkedIn, returned 404 in production. Browsers never load that file when you visit a page, so nothing looked broken. Every build was green. The file was in the repository. And the URL was dead. If you want the ending first: declaring any entry under module.mounts for a target root replaces Hugo’s default mount for that root. I had mounted one subfolder of static, and in doing so had silently unmounted everything else in it.

Thursday, July 23, 2026 | 3 minutes Read
Hero Image
The SQLite trap caught me the same day I wrote about it

I recently published a post about running SQLite in production, and the heart of it was a warning: on a platform with an ephemeral filesystem, a mis-pointed SQLite file means your database quietly ceases to exist on every redeploy. I even described my defence with some pride. The app refuses to accept a raw connection string and builds its own from a SQLITE_DIR environment variable, so nobody can get the path wrong.

Thursday, July 23, 2026 | 4 minutes Read
Hero Image
My folder locker never locked anything

In February 2025 I wrote a folder locker: a Windows batch script with a password prompt, a folder that vanishes from Explorer, and a README describing it as secure. The password was sitting in the script in plain text. The files were never encrypted. What the script actually did was rename a directory, and it took me three versions across seventeen months before the documentation said so plainly. The entire lock Here is the mechanism, in full:

Wednesday, July 22, 2026 | 6 minutes Read
Hero Image
Running SQLite in production (yes, really)

I recently shipped a small Flask app, a scoring platform for a fitness competition, with SQLite as its only database. Not as a stopgap until the real database arrives: the app refuses to start with anything else, because a half-supported second database is worse than none. The conventional advice says this is a mistake. For this class of app, the conventional advice is wrong, but the deployment details will bite you if nobody warns you about them.

Wednesday, July 22, 2026 | 5 minutes Read
Hero Image
When RAID1 saved the data but not the state

My home server is a ZimaBoard 2 running ZimaOS. The storage that matters is a RAID1 mirror, two 4 TB drives formatted BTRFS, holding a media library, backups, and personal archives, with the Docker application stack running off the same pool. It is a small setup, and for a long time it was a boring one, which is exactly what you want from storage. Then a migration went wrong, and it taught me more than a year of everything working ever did.

Monday, January 12, 2026 | 4 minutes Read
  • ««
  • «
  • 1
  • 2
  • »
  • »»
Navigation
  • About
  • Skills
  • Projects
Contact me:
  • [email protected]
  • B3ardBr0
  • Wilhelm Maritz

Toha Theme Logo Toha
© 2026 Wilhelm Maritz
Powered by Hugo Logo