Please remove all base path mappings related to the RestApi in your domains’

Sometimes CloudFormation fails to delete a RestAPI in an API Gateway. Finding the base path mapping and deleting it in the AWS Console GUI can be an epic PITA. Fortunately there is a magical incantation for clearing it out: “(none)”

Then go back and delete your stack again.

Sometimes you go to delete a CloudFormation stack or destroy some Terraform and the run fails to delete an ECR repo because the repository still contains images.

The following resource(s) failed to delete: [ECRRepository].
The following resource(s) failed to delete: [ECRRepository].

Here is a quick and dirty way to empty that repo before you retry your delete. Excuse the ugly python. Its a one-off script not a maintained project. 😉

Invoke it like this: ./ my-ecr-repo-name

Then go back and press delete on your CloudFormation stack and voilà!

Easy credit card number validation

Photo by MARK S. on Unsplash

Luhn Algorithm is a formula for checksumming credit card numbers. It won’t tell you whether the right card number was entered nor whether the card can Auth, but it will tell you whether the number is a valid card number. So it’s a useful input validation to verify someone didn’t typo their card or simply send you garbage data.

I once used Luhn in a SaaS security scanner product to narrow down lists of potentially leaked credit card numbers in cloud storage. I think that might be the less common use case.

Wikipedia describes the formula like this…

From the…

or why range-v3 is 🔥 and you should use it now

Photo by Avel Chuklanov on Unsplash

An ABA Routing Transit Number is a nine digit code printed at the bottom of your checks. Let’s be real though. It’s 2020 not 1910. You don’t have paper checks anymore. But I bet you do use ACH for direct deposit paychecks or to pay your rent. The ACH network uses RTNs to route payments to the correct bank that manages your account.

Let’s google my routing number and use it as an example.

This was surprisingly hard to find.

Photo by Caspar Camille Rubin on Unsplash

My first few Google results were Windows specific. Who writes software for Windows anymore? Not me. Hard pass.

After that the next solution depends on curses. I don’t want to link against curses. Pass.

Enter termios. It works on my MacBook. It works on Linux. No linking. No installs. Let’s go.

Let’s try it out.

$ ./a.out
Username: ryang

Apparently libc used to implement this in getpass(3), but it was deprecated.

This function is obsolete. Do not use it. If you want to read input
without terminal echoing enabled, see the description of the ECHO
flag in termios(3).

The general guidance is to write your own version just like we did. Okay then.

ABR — Always Be Rebasing. Thats our mantra. It’s one of those small software industry things everyone has to learn. But it doesn’t seem to be taught anywhere other than blog posts and by annoyed coworkers.

Photo by Yancy Min on Unsplash

This is how you start your day. Roll out of bed, open laptop, start Spotify, rebase. Now go make coffee.

The most basic use case for git rebase is keeping your development branch up to date with trunk. Whether that refers to master, develop, or your favorite epic or feature branch is up to you and your team. …

Photo by Nathan Dumlao on Unsplash

Track2 is an American Banking Association (ABA) format for storing information on the magnetic stripe on your credit card. Track2 is also included in EMV chip results under tag 57.

Example Track2 from a dead card


The semicolon is a header. The next ~19 digits are the card number. The equal sign is a field separator. The next 4 digits are expiration in YYMM format. The question mark is the trailer. And so it goes.

Looks easy to pull apart with a regular expression or a simple parser, right?

Well, yes. But also no.

This is what you’ll actually…

git allows you to squash multiple commits into one.

I tend to work in dev or feature branches with pretty dirty git logs. Once my code passes tests, squash allows me to go back and combine my fragmented commits into a single atomic commit representing a feature. As a bonus git bisect will actually work once you’ve set the expectation that every commit in master should build and pass tests.

Github method — Press Button

You can wait until its time to merge your Pull Request in Github and squash the entire thing there. Just press the button and everything is done for you.


I recently had to brush up on character encoding. I hate even uttering that phrase. Not because it implies I keep relearning the same things, pasting the results into Evernote, and then forgetting until it becomes relevant again five years later. No, I hate it because I wish the whole world used unicode and everything around it was abstracted away into neat little library functions.

I lied. I secretly love ASCII and every sneaky little trick that goes with it. Just like I love x86 assembly language, Tcl, and the low resolution snow flake screensaver from my old FreeBSD desktop…

Installing a header-only library

I recently set out to publish my first header-only library, but I found most of the existing examples to be extremely dense. They were all well maintained and supported dozens of linters, formatters, and package managers. Some were even skeleton projects for quickly stamping out the boilerplate necessary to create a new library. I could have used hpp-skel as my template and been off to the races adding my own code. But I wanted to understand every line of code in my new repository and to do that I knew I would need to start small. I needed hello world.

Ryan Graham

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store