Full Width [alt+shift+f] Shortcuts [alt+shift+k]
Sign Up [alt+shift+s] Log In [alt+shift+l]
6
A few weeks ago, I was building a server-side API client. I had written the code and tested it in isolation. Everything looked good. Unfortunately, when I included it in the main service, I started seeing errors. I decided to try asking an AI tool for suggestions. I gave it the error message and a bunch of context. It gave me a solution with a detailed explanation. The errors went away. But the solution didn’t sit right with me. It was a bit complex, introducing more layers of code and various protections. The errors were gone, but I couldn’t clearly explain why it worked, and that was bothering me. While the code was being reviewed, I decided to take another look. I brought back the error and spent some time digging into the stack trace. That’s when I made the discovery: it was an environment issue. All I needed to do was set an environment variable and the issue would be fixed. The AI-provided code had been masking the real issue, quietly suppressing the error, and hiding the truth...
3 days ago

Improve your reading experience

Logged in users get linked directly to articles resulting in a better reading experience. Please login for free, it takes less than 1 minute.

More from Bryan Braun - Blog

Made in 2024

Here are some things I made in 2024: Music Box Fun: Advanced Editing (a new major feature): Adds multiple-note selection for bulk operations on notes (like deletion, copy/paste, nudging and dragging) Also includes a “space editor” for arbitrarily adding/removing space anywhere in the song Includes other niceties like note highligting during playback and pitch highlight on hover Music Box Fun songs I made: Elliott’s Theme (Stardew Valley) in 15-note and 30-note versions Bluey Theme Song Jupiter Theme (The Planets) 11 new projects added to Let’s Get Creative, now available at a new domain name: https://letsgetcreative.today The Firefly Building in Minecraft (if you know, you know) 13 blog posts on bryanbraun.com, including a companion repo to my post on unusual Git IDs. I’m happy with this list. It was a year of many challenges. In February we got hit by a flooded basement and an emergency hospitalization which left my wife with limited mobility for a month. It was a difficult time and I’ll be forever grateful for the family and friends who helped us get through it. It was also a year of growth for my kids in particular, bringing many new parenting challenges. At the same time, I have so much to be grateful for. My wife and I hit our fifteenth anniversary and our relationship has grown stronger despite (or perhaps because of) the storms we’ve weathered. Every year brings new opportunities and challenges and it’s a privilege to have a committed partner that I can face them with. 🚵🏻‍♀️🚵🏻‍♂️ I wish you all the very best in 2025.

a month ago 38 votes
Links #11

Here are some more links to things that I keep thinking about. I shared a bit more detail on these ones than I usually do—there were so many good quotes to include. Enjoy! Selfishness & Therapy Culture Earlier this year, there was a post in the New York Times called “Sometimes, Forgiveness is Overrated”. Selfishness & Therapy Culture is a brilliant critique, both of the NYT post and of the culture that produced it. “Who in the world could possibly look out at contemporary society and think that the message ‘put yourself before other people’ isn’t loud enough? Every women’s site on the internet preaches this message. Every hustle bro on Threads preaches this message. Every therapist between San Diego and Sacramento preaches this message. Every eight-word meme in overly elaboratee cursive font on Pinterest preaches this message. … There’s the girlboss version and the Joe Rogan bro version and horoscope obsessive version and the Wall Street grindset version and the fitness guru on trenbolone version…. Justification for selfishness is not in short supply. It is the water in which we swim.” My opinion: the celebration of selfishness is a form of societal sickness that we have, and it isn’t new. Faith practices that center on forgiveness and selflessness are part of the social infrastructure our forefathers erected to fight the sickness, and when we erode them, we do so at our own peril. The Morality of Having Kids in a Magical, Maybe Simulated World This post is a reaction to the recurring sentiment that perhaps it is immoral to have children in a world threatened by climate change. The “evidence for a simulated world” part is a bit farfetched, but what interested me the most was the idea of framing human progress in the terms of “ENERGY: The Game.” It gave me this feeling like, oh, we’re all collectively playing this game1, and it’s going somewhere, so what is my role? Instead of playing for myself, or my family, or my country, I could be playing for humanity, in its fight against the elemental foe. In this game, is there anything more noble then working to push technology forward, creating value out of nothingness, helping to create abundance for all humanity? You should be working on Hardware I work in software but I studied mechanical engineering, so I have a deep respect for those who work in hardware (like Casey Handmer, the author). I love how this post calls out the needs in the world and raises your aspirations to work on them: “You only get a few chances to work on really big projects, to build the future, to move humanity forward.” “Most hardware concepts will never even be dreamed, let alone designed, built, and brought to market. There are many, many more important, good businesses to build than there are people building them. When you build something, you can accelerate the future by decades!” The whole post is inspiring, not to mention the follow-up post How to learn Hardware, which included this wisdom: “It is always easier to learn things you enjoy doing. The art lies in finding ways to enjoy the things that are necessary…. and finding ways to avoid enjoying to excess things that are counterproductive to your mission in life.” The Well-Rounded Engineer Another one from Casey Handmer (I’ve been reading through his archives). In this one, he explains that all nontrivial engineering efforts eventually encounter “the coordination problem.” It is very common for engineers to be oblivious of it, which manifests itself in things like complaints about management being inept, or resentment that their work was “thrown away.” Here, Casey argues that elite engineers should understand the coordination problem, what causes it, and ways to resolve it. I’ve historically avoided the management track because I enjoy creating things and people are messy. That said, management exists to help solve the coordination problem and this post helped me see that I ought to develop a working understanding of management if I ever want to create something nontrivial (and I do!). Casey’s blog has quickly become one of my favorites. You Don’t Have Time to Read Books That Won’t Change Your Life We’ve all read a book that changed our life, right? Given that there’s 50 million+ books in existence, there are likely hundreds of thousands of other life-changing books out there that we only haven’t read because we haven’t found them yet. This post pushed me to imagine what my life might look like if I read twice as many “life-changing books” as I currently do, and how I might do that. I’ve been on a reading kick recently (a book a week for the past six weeks!) and I feel like it’s added a richness to my life that I don’t get from podcasts or music. 1 "It's like we got handed a save file of a game, where others put in millions of hours of work, and we can decide what game we want to play in the future." - Kurzgesagt

2 months ago 23 votes
Unusual Git IDs

You can search Github for unusual commit IDs: There are over 2k commits starting with 0000000! While looking for commits like these, I started to become suspicious that people were intentionally modifying their commits IDs to be unusual: A commit ID of eeeeeee, with a message of "eeeeeee", created by a user named "eeee". What are the odds that this user happened to commit seven consecutive commits, all with an ID of "defaced"? Sure enough, there are tools you can use to generate “vanity” commit IDs (like git-vanity-hash). These tools work by using the “brute-force” method. Basically, they create a commit, check the hash, and if it doesn’t match, they increment a piece of data in the commit header and try again. That’s pretty clever but I’m more interested in unusual commit IDs that occur naturally. How often do they happen? Have I ever created one before? Searching my commits I decided to use Github’s CLI tool, gh, to query the Github API and pull down a list of my public commits: gh search commits --author bryanbraun --json commit --jq ".[].commit.tree.sha" --limit 1000 This worked but it has a maximum limit of 1000 commits (my public total is closer to 4k). Eventually, I found a way to get them all by writing a bash script to break up my queries by year, generating one file per query, and combining the files when done: #!/bin/bash # To prevent API rate limits, set a personal access token to the GITHUB_TOKEN # environment vairable in your terminal before running this script. username="bryanbraun" start_year=2012 end_year=2024 # Create a file for each year for year in $(seq $start_year $end_year); do next_year=$((year + 1)) echo "Fetching commits from $year to $next_year..." gh api -X GET \ "/search/commits?q=author:$username+committer-date:$year-01-01..$next_year-01-01" \ --header "Accept: application/vnd.github.cloak-preview" \ --paginate \ -q '.items.[].sha' >> "commits-$year.txt" done # Combine all files into one cat commits-*.txt > all_commits.txt # Remove unused files for year in $(seq $start_year $end_year); do rm "commits-$year.txt" done The result is a 4000-line file with one commit ID per line: Now I just needed to scan my commit IDs for unusual patterns. Grep is good at this kind of thing so I put together a bash script that uses grep to do various checks: #!/bin/bash # Define the input file containing commit SHAs input_file="all_commits.txt" echo "Analyzing patterns in the first 7 characters of commit SHAs..." # Check 1: SHAs where the first 7 characters are the same echo "\n1. SHAs where the first 7 characters are the same:" grep -E '^(.)\1{6}' "$input_file" # Check 2: SHAs starting with a palindrome (e.g., "abcdcba") echo "\n2. SHAs starting with a palindrome:" grep -E '^(.)(.)(.)(.)\3\2\1' "$input_file" # Check 3: SHAs where the first 7 characters form an ascending sequence echo "\n4. SHAs where the first 7 characters form an ascending sequence:" grep -E '^(0123456|1234567|2345678|3456789|456789a|56789ab|6789abc|789abcd|89abcde|9abcdef)' "$input_file" # Check 4: SHAs where the first 7 characters form a descending sequence echo "\n5. SHAs where the first 7 characters form a descending sequence:" grep -E '^(fedcba9|edcba98|dcba987|cba9876|ba98765|a987654|9876543|8765432|7654321|6543210)' "$input_file" # Check 5: SHAs where the first 7 characters form a repeating pattern (e.g., "abababa") echo "\n6. SHAs where the first 7 characters form a repeating pattern:" grep -E '^(.)(.)\1\2\1\2\1' "$input_file" # Check 6: SHAs where the first 7 characters are vowels only echo "\n7. SHAs where the first 7 characters are vowels only:" grep -E '^[aeiouAEIOU]{7}' "$input_file" I ran this and got something! One of my commits was a palindrome: c5a7a5c c5a7a5c, my most unusual commit ID, was created over ten years ago! It’s not the most beautiful commit ID but I’m pretty happy that I found something. What else could we do? My list of checks was pretty short, so we could expand it if we wanted. Here are some ideas: Check if the first seven characters are all letters, or all numbers (e.g., “afddcbf”, “2950312”). Check if the first seven characters are composed of only two distinct characters (e.g., “a44aaa4”). Check commit IDs against a list of words constructed from hexadecimal characters (e.g., “baff1ed”). Check if the first seven characters are in alphabetical order (e.g., “accdfff”). Check if the first seven characters are in numerical order (e.g., “0035789”). Check for interesting patterns outside of the first 7 characters of the commit ID. I actually tried that first idea but I found that the “all numbers” case was too common (it found over a dozen matches in my commit history). You gotta strike the right balance. It would be fun to put together a web interface where people could put in their Github username and scan their own commits, but I’ve come to terms with the fact that there’s not enough time in the world to build all the interesting little websites that ought to exist. I used ChatGPT to help me build the scripts, which made it possible to punch out this analysis in a single afternoon. If it took any longer, I likely wouldn’t have attempted it. This is a perfect example of AI-enhanced development making me more ambitious with my projects. I put all the scripts in a public repo at bryanbraun/unusual-commit-ids. Feel free to fork it, download it, and scan your own commits. If you find any unusual commits in your own history, you should share them in the comments (naturally occurring commits only)! Finally, if you thought this was interesting, you may like my other git commit-related projects: Commit colors Commit haikus (a now-retired twitter bot)

3 months ago 20 votes
Setting up your /now page with an RSS feed

I have a /now page, which I use to tell people what I’m up to these days. I like the concept of “now pages” but I felt like it would be better if it had an RSS feed. The feed would give interested parties a way to subscribe to life changes. The problem is that RSS feeds aren’t really designed for a single page. It’s more for a content collection, like blog posts or podcasts. Still, is there a way to make it work? To have a single page, publishing to subscribers every time it’s updated? Unique IDs In RSS feeds, each entry is supposed to have a unique ID. Here are some examples: Atom <entry> <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id> <title>Atom-Powered Robots Run Amok</title> <link href="http://example.org/2003/12/13/atom03"/> <updated>2003-12-13T18:30:02Z</updated> <summary>Some text.</summary> </entry> JSONFeed "items": [ { "id": "1", "content_html": "<p>Hello, world!</p>", "url": "https://example.org/initial-post" } ] These IDs are intended to be globally unique and unchanging: id (required, string) is unique for that item for that feed over time. If an item is ever updated, the id should be unchanged. New items should never use a previously-used id. JSONFeed Version 1.1 Docs Changing the ID is bad because it causes old posts to resurface as new posts in people’s feed readers. Usually you don’t want this, even when you’re updating an old post. But in my case we do want this. If I only publish a single entry and include the current date in the ID, it’s unique every time I rebuild the feed (i.e., whenever I update the /now page). And just like that, every update is a new publish. Is this bad and should I feel bad? I’m deliberately disobeying the spec to get the result I want. Often, in the dev world, these kinds of things come back to bite you. Is there a better way to do this? Well, I could treat my /now page as a content collection, with each new entry being published as new post, never deleting or overwriting old entries (basically a microblog just for life updates). It’s doable, but it diverges from the simplicity of having a single document at a single url. At that point, I might as well insert life updates into my normal blog, which works but isn’t appropriate for many types of blogs. One issue with changing IDs is that small revisions to the /now page republish the whole page, making it hard for subscribers to see what changed. I could mitigate this by including a link to the diff on Github (version control FTW!), but it’s not the most user-friendly solution. Anyway, I’m going to roll with it for now. If anyone wants to do a similar experiment, feel free to check out the feed template in my repo.

3 months ago 14 votes

More in technology

The 2024 Arduino Open Source Report is here!

Every year, we take a moment to reflect on the contributions we made to the open source movement, and the many ways our community has made a huge difference. As we publish the latest Open Source Report, we are proud to say 2024 was another year of remarkable progress and achievements. A year of growth and […] The post The 2024 Arduino Open Source Report is here! appeared first on Arduino Blog.

22 hours ago 2 votes
On the new iPhone 16e

Today Apple unveiled the iPhone 16e, which they're calling a part of the iPhone 16 lineup now, rather than this odd duck the SE had been since launch. Honestly, I think this move in particular is interesting and maybe makes a ton of sense, but let's

18 hours ago 2 votes
Just Stop Oil is doing more harm for the cause than good

Mitigating climate change requires more than poems and protest

2 hours ago 1 votes
This mod simplifies single-point threading on mini lathes

“Single-point threading” on a lathe is the process of cutting threads, such as for a bolt, into the material through turning. The spindle/workpiece spin and the carriage moves linearly at a precise amount per turn of the spindle. That linear movement is the thread pitch. But this process usually requires several passes to reach the […] The post This mod simplifies single-point threading on mini lathes appeared first on Arduino Blog.

yesterday 3 votes
YOLO-squashing our Django repository

Buttondown's core application is a Django app, and a fairly long-lived one at that — it was, until recently, sporting around seven hundred migration files (five hundred of which were in emails, the "main" module of the app). An engineer pointed out that the majority of our five minute backend test suite was spent not even running the tests but just setting up the database and running all of these migrations in parallel. I had been procrastinating squashing migrations for a while; the last time I did so was around two years ago, when I was being careful to the point of agony by using the official squash tooling offered by Django. Django's official squashing mechanism is clever, but tends to fall down when you have cross-module dependencies, and I lost an entire afternoon to trying to massage things into a workable state. This time, I went with a different tactic: just delete the damn things and start over. (This is something that is inconsiderate if you have lots of folks working on the codebase or you're letting folks self-host the codebase; neither of these apply to us.) rm rf **/migrations/* worked well for speeding up the test suite, but it was insufficient for actually handling things in production. For this, I borrowed a snippet from django-zero-migrations (a library around essentially the same concept): from django.core.management import call_command from django.db.migrations.recorder import MigrationRecorder MigrationRecorder.Migration.objects.all().delete() call_command("migrate", fake=True) And voila. No fuss, no downtime. Deployments are faster; CI is much faster; the codebase is 24K lines lighter. There was no second shoe. If you were like me 24 hours ago, trying to find some vague permission from a stranger to do this the janky way: consider the permission granted. Just take a snapshot of your database beforehand just in case, and rimraf away.

yesterday 2 votes