← back to blog
CI/CD passing · 30 August 2025 · 4 min read

Two Boring Pipeline Bugs That Teach a Bigger Lesson

CI/CDPlatform EngineeringAutomation

Pipeline configuration doesn’t get the same scrutiny application code does. It’s YAML, it’s usually small, and it’s easy to assume that if it were wrong, something would obviously fail. Two small, real bugs are worth holding onto as evidence that this assumption isn’t safe.

Bug one: an empty string is not a neutral default

A jumpbox deployment’s config had an image_id field set to "". Nothing rejected it, nothing warned about it — the pipeline treated a blank string as valid input and proceeded, and the resulting instance simply booted without a pinned golden image. It took a separate, unrelated investigation to notice that the field was blank at all.

# looked harmless, wasn't:
image_id: ""
image_region: ""

The fix was two lines — pin both the image and its region together. The actual lesson is upstream of the fix: a required field with no valid empty state needs a schema that rejects blank, not a human who happens to notice. If image_id: "" had failed pipeline validation immediately, this would have been a thirty-second fix at commit time instead of a quietly-degraded deployment discovered later, elsewhere, by accident.

Bug two: a pipeline stage for a component that doesn’t exist

A CI config carried a deploy stage — enabled: true, wired to a real team — for a component that had no matching folder, chart, or code anywhere else in the repository. It wasn’t doing anything harmful; it was just running, as a no-op, referencing nothing. It had clearly been left behind after whatever it originally deployed was removed, and nothing ever flagged the orphan.

The general shape is worth watching for in any pipeline config: a deploy-* (or equivalent) entry with no component backing it is a red flag by construction, not something that needs a judgment call. It’s a mechanical check — for every deploy stage, does the thing it deploys still exist in the repo — and it’s cheap to write once and run on every pipeline config change.

Why these are the same bug, really

Both slipped through because pipeline YAML gets treated as configuration, not code — reviewed for intent, not validated for correctness. Application code has linters, type checkers, and tests that fail loudly on exactly this class of mistake: a value that’s technically well-formed but semantically wrong, or a reference to something that no longer exists. Pipeline definitions rarely get the same treatment, even though they’re just as capable of silently degrading a deployment or wasting a pipeline run on nothing.

Neither fix here was hard. The useful takeaway isn’t the two specific bugs — it’s that a CI config schema that rejects blank-but-load-bearing fields, plus one script that checks every deploy stage against the component tree it claims to deploy, would have caught both before either one shipped.