Back to blog
#pipelines#developer-experience#visual-editor

Why I don't use YAML for pipeline config

YAML is where developer joy goes to die. Pipelines are graphs, not text files. Here's why Zowl uses a visual editor.

Why I don't use YAML for pipeline config

I've suffered enough

I have strong feelings about YAML. They're all negative.

In a previous life I maintained a CI/CD setup with about 40 pipeline definitions across three repos. Every single week someone would open a PR with a YAML indentation bug. Two spaces instead of four. A tab that snuck in. A multiline string that broke because someone forgot the pipe character. I once watched a senior engineer spend 45 minutes debugging a deploy failure that turned out to be a single trailing space on line 87 of a 200-line YAML file.

YAML doesn't have your back. It has a knife behind it.

The config file lie

Here's the argument people make for YAML pipelines: "it's just config, it should live in a text file, version controlled, plain and simple."

I bought that argument for years. And it works fine when your pipeline is linear. Step A, then step B, then step C. A text file can represent that.

But real pipelines aren't linear. Real pipelines have retry loops. They have conditional branches where failure on step 2 routes to a different path than success on step 2. They have fan-out steps where one input spawns multiple parallel tasks. They have fallback chains where if agent A fails, try agent B with a modified prompt.

Try representing this in YAML:

pipeline:
  - step: pre-check
    agent: claude-code
    on_success: implement
    on_failure: rewrite-prd
    retry:
      max: 2
      backoff: exponential
  - step: rewrite-prd
    agent: claude-code
    on_success: pre-check
    on_failure: abort
  - step: implement
    agent: codex
    on_success: validate
    on_failure: implement-retry
    retry:
      max: 3
      backoff: linear
  - step: implement-retry
    agent: claude-code
    fallback_for: implement
    on_success: validate
    on_failure: abort
  - step: validate
    agent: claude-code
    on_success: complete
    on_failure: implement
    max_cycles: 3

Can you see the retry loop between validate and implement? Can you see that pre-check failures route to a PRD rewrite step that then loops back? Can you see the fallback chain from Codex to Claude Code?

You can figure it out if you stare at it. But you can't see it. And that distinction matters at 11pm when you're building tomorrow's overnight pipeline.

Pipelines are graphs

This is the thing that finally clicked for me. A pipeline isn't a list of instructions. It's a directed graph. Nodes are steps. Edges are transitions. Some edges are conditional. Some form cycles. Some fan out.

Graphs have a natural visual representation. You draw boxes and arrows. You've been drawing them on whiteboards since your first CS class.

Text files are terrible at representing graphs. You end up encoding spatial relationships (which step connects to which) as key-value pairs. The structure is there, but it's implicit. You're reading a data structure through a keyhole.

When I was building nightloop.sh, this wasn't a problem because the pipeline was dead simple: pre-check, implement, validate, done. Three steps in a line. But the moment I added retry logic and failure routing, the bash script became unreadable. And converting that to YAML wouldn't have made it better, just differently unreadable.

What a visual editor gives you

When I built Zowl's pipeline editor, I had one constraint: you should be able to understand any pipeline in under five seconds. Not read it. Understand it.

You open the editor and you see boxes. Each box is a step with a name, an agent assignment, and a prompt summary. Arrows connect the boxes. Green arrows for success paths. Red arrows for failure routes. Dashed arrows for retry loops. You can see the entire flow at a glance.

Want to add a retry loop? Drag an arrow from the failure output of step 3 back to step 3's input. Set the retry count. Done. In YAML that's six lines of config that you have to mentally trace to verify.

Want to add a fallback agent? Drop a new step box, connect it to the failure output of the original step, assign a different agent. You can see both paths side by side. In YAML you're scrolling up and down trying to match on_failure: some-step-name to the step with that name 40 lines below.

The visual editor also catches mistakes that YAML never would. If you create a cycle with no exit condition, the editor highlights it in yellow. If a step has no incoming connections (orphan node), it flags it. If you've got a retry loop with no max count, it warns you. YAML will happily let you define an infinite loop and you won't find out until 3am when your token bill starts climbing.

But what about version control?

This is the first objection I always hear. "If it's visual, how do you version control it?"

Zowl stores pipeline definitions as JSON under the hood. The visual editor is just a view layer on top of a structured data model. You get the same deterministic output every time. The JSON diffs cleanly in git. It's just not something you edit by hand, because you don't need to.

Think about it this way: nobody edits their Figma designs as SVG source code, even though SVG is a text format that diffs in git. The visual tool is the interface. The file format is the storage layer. Conflating the two is how we ended up editing 200-line YAML files by hand in the first place.

The real cost of YAML

Here's the part that actually bothers me. YAML pipeline config has a hidden tax that nobody tracks: the time you spend debugging the config instead of the pipeline.

When a pipeline fails, the first question should be "what went wrong with the task?" Instead, the first question is usually "did I mess up the config?" Is the indentation right? Did I spell the step name correctly in the on_failure reference? Did I accidentally use a tab? Is that string quoted properly?

You're debugging your build system instead of your build. That's backwards.

I tracked my own time on this back when I was using a YAML-based config for nightloop.sh (yes, I went through a YAML phase, don't judge me). Over two weeks, I spent roughly 3 hours debugging YAML parsing errors, broken references, and indentation issues. Three hours that had zero value. The pipelines weren't better for it. The tasks didn't ship faster. I just fought with a file format.

A graph deserves a graph editor

I don't think YAML is evil. It's fine for simple key-value config. I use it for stuff like setting default token limits or agent preferences. Flat config, no nesting beyond one level, no references between sections. YAML does that fine.

But the moment you're representing flow control (conditionals, loops, branches, parallel execution) you need a tool that shows flow, not a text file that describes it. The shape of your pipeline (whether linear or with complex branches) deserves to be visible.

Zowl's pipeline editor exists because I got tired of holding a graph in my head while reading a text file. If you're coming from a bash script approach, you'll appreciate understanding how pipelines evolved from shell scripts. The visual editor should've been the default all along.