Norway stopped existing for us on a Thursday. Not the actual country: every Norwegian user suddenly failed a check that passed for everyone else, and the logs had nothing useful to say.
The Scene
We were expanding payments to the Nordics, so I added a markets.yaml file with the supported countries. The billing service reads it on boot and checks users against it. Swedish and Danish test accounts sailed through. The first Norwegian signup failed with “country not supported”, which is funny, because Norway is on the pricing page.
The Investigation
First suspect: the API. The logs show country=NO arriving exactly as sent, so the frontend is innocent.
Next, the eligibility function. Read it three times, found nothing, then reached for my favorite theory: caching. I restarted the service. Twice. (Most of day one went here.)
Day two I stopped guessing and printed the list:
print(supported)
# ['SE', 'DK', False, 'FI']
Three country codes and a boolean, sitting in the middle like it pays rent.
The Discovery
The file said
- NO. PyYAML follows the 1.1 spec, wherenois a boolean, same asyes,onandoff. The parser read it asFalse, so the list containedFalsewhere Norway should have been.
Here’s the thing: I wrote that line myself two weeks earlier. I also wrote - SE and - DK right next to it, and those parsed fine, which is why my eyes never flagged the one that didn’t.
The Fix
Quotes:
supported:
- "SE"
- "DK"
- "NO" # because YAML 1.1 thinks bare NO is false
- "FI"
Then I grepped the repo for bare YES, NO, ON and OFF and found two more, including a rollback flag in a deploy config that had meant false all along. Nobody noticed because false was what it did anyway.
The Lesson
- Quote anything that reads like English. Country codes, status labels, currency names. If a value could double as an English word, the parser gets an opinion about it, and its opinion is boolean.
- Test the weird case, not just the happy path. Everyone tested Sweden and Denmark because they worked. Nobody opened a Norwegian account until a customer did it for us.
- Read the spec eventually. I’d written YAML for six years without learning that 1.1 keeps a secret list of booleans. This bug taught me for free, if you don’t count the two days.
What I’d Do Different
- Add a config test the same day we add a country. Five lines of pytest catches it on Thursday, not Sunday.
- Lint configs in CI for unquoted
yes,no,on,offvalues. One grep, zero archaeology. - Trust support tickets sooner. The first Norwegian report described the exact failure in line one, and I skimmed it as routine.
External Resources
The YAML 1.1 spec lists the boolean values, the PyYAML documentation shows how values get resolved, and the Wikipedia article on YAML covers what changed in 1.2.
Final Thoughts
So yeah. Two days to learn that in YAML 1.1, Norway isn’t a country, it’s a boolean. The fix took ten seconds. The repo-wide grep took an hour and found a config value that had been lying to us for months, so on balance the bug paid for itself. Barely.
