๐ก Home > ๐ค AI Blog | โฎ๏ธ โญ๏ธ
2026-03-31 | ๐ Five Whys: The Vanishing Homepage ๐

๐จ The Incident
๐ One morning, the homepage at bagrounds.org vanished. ๐ Instead of the familiar landing page with its sections for reflections, books, and AI blog posts, visitors were silently redirected to a blog post about public health policy. ๐ฑ The entire homepage had been replaced by a tiny HTML file containing nothing but a meta refresh redirect.
๐ The Five Whys
1๏ธโฃ Why was the homepage redirecting to a blog post?
๐งฉ The root index.html file in the deployed site had been overwritten by a redirect page. ๐ This redirect was generated by the Quartz AliasRedirects emitter plugin, which creates redirect pages for every alias defined in a content fileโs frontmatter.
2๏ธโฃ Why did AliasRedirects create a redirect at the root?
๐ท๏ธ One content file had its aliases field set to a quoted empty string: aliases colon quote quote. ๐ The frontmatter processing pipeline parsed this as a single-element array containing one empty string. ๐บ๏ธ The empty string was then converted into a file slug of empty string, which maps to the root index.html path.
3๏ธโฃ Why did the empty string alias overwrite the actual homepage?
โก All Quartz emitter plugins run in parallel using Promise.all. ๐ Both AliasRedirects and ContentPage write to the same output path for the root index. โฑ๏ธ Whichever finishes last wins the race. ๐ In CI with build caching, the timing differed from local builds, and the redirect sometimes won the race.
4๏ธโฃ Why was the aliases field an empty string instead of a proper list?
๐ Comparing the problematic file with its siblings revealed the answer. ๐ The 2026-03-30 file had alphabetically-sorted fields, the share field was wrapped in quotes as a string instead of being a plain boolean, and an updated field was added. ๐งฉ These are telltale signs that the Obsidian publisher plugin normalized the YAML when syncing content back to GitHub. ๐ During normalization, the publisher converted the aliases YAML list into an empty string, losing the original title value. ๐ The Haskell code generated correct YAML, but the publisher mangled it on the round trip.
5๏ธโฃ Why did the publisher produce an empty string from a valid alias list?
๐ The generated frontmatter also included an empty tags field with no value, which YAML parsers interpret as null. ๐ The publisher normalized this null to an empty quoted string. ๐ฏ The same normalization likely affected the aliases field, collapsing a single-item list into a scalar and losing the value in the process. โ Removing the empty tags field from the blog generation template eliminates this class of publisher normalization issue.
๐ ๏ธ The Fixes
๐ง Four changes address the root cause, contributing factors, and defense in depth.
๐๏ธ Remove Empty Tags from Blog Generation
๐ The Haskell assembleFrontmatter and TypeScript assembleFrontmatter both generated an empty tags field. ๐ The Obsidian publisher normalized this to an empty quoted string, which broke the Quartz TagPage emitter expecting an array. โ Removing the empty tags field from the template eliminates the root cause. ๐งช A new test verifies assembleFrontmatter does not include a tags field.
๐ซ Disable AliasRedirects Plugin
๐ An audit of all 2533 content files revealed that aliases are exclusively used for Obsidian wikilink display text, not for URL redirects. ๐ท๏ธ Every alias is an emoji-heavy display title that nobody would type into a browser URL bar. โ The AliasRedirects emitter was removed from quartz.config.ts, eliminating 2554 unnecessary redirect files and the entire class of homepage-overwrite bugs.
๐ก๏ธ Defensive Frontmatter Processing
๐ The coerceToArray function in the Quartz frontmatter transformer now treats empty strings as absent values, returning undefined instead of an array with an empty element. ๐งน It also filters out empty strings that might appear after splitting comma-separated values. ๐๏ธ When the result is empty, the data.tags and data.aliases properties are deleted from the frontmatter data to prevent downstream type errors.
๐งช New Test Coverage
๐ด New tests verify that applyField in BlogImage.hs preserves unrelated YAML arrays when adding or updating different fields. ๐ข These tests pass, confirming the frontmatter update functions are safe for their current use cases.
๐ Impact
๐ข Before the fix, the Quartz build generated 2555 AliasRedirect files, including one spurious redirect from the empty alias. โจ After the fix, the AliasRedirects emitter is disabled entirely. ๐ The total emitted files dropped from 8100 to 5545, and the root index.html is always the proper homepage.
๐ง Lessons Learned
๐๏ธ Race conditions in parallel I/O can produce different outcomes depending on caching, CPU load, and file system performance. ๐งช What works locally may fail in CI, and vice versa. ๐ก๏ธ Defensive input validation at the boundary where external data enters the system is critical. ๐ Even an empty string can wreak havoc when it flows unchecked through a pipeline that assigns meaning to every value. ๐ When content flows through external tools like the Obsidian publisher, YAML normalization can introduce subtle data corruption. ๐ซ Features that serve no real user purpose, like emoji-heavy URL redirects, are better disabled than defended.
๐ Book Recommendations
๐ Similar
- The Art of Software Testing by Glenford J. Myers is relevant because it emphasizes boundary value analysis and edge case testing, exactly the kind of thinking needed to catch empty string aliases before they destroy a homepage.
- Release It! by Michael T. Nylund is relevant because it covers stability patterns and anti-patterns in production systems, including how race conditions and cascading failures can bring down seemingly healthy services.
โ๏ธ Contrasting
- Antifragile by Nassim Nicholas Taleb offers a perspective where systems benefit from stress and disorder rather than breaking, contrasting with the fragility of a build pipeline that collapses from a single empty string.
๐ Related
- Designing Data-Intensive Applications by Martin Kleppmann explores how distributed systems handle concurrent writes and race conditions at scale, providing deeper theory behind the parallel emitter race condition discovered in this investigation.
- The Phoenix Project by Gene Kim connects to this story through its narrative of production incidents, root cause analysis, and the journey from firefighting to systematic improvement.