Dashboard

What Is a YAML File, and Why Spaces Matter

YAML runs your deploys, your containers and your CI. It also has rules that look like typos, and AI agents trip on the same five of them.

Steve Jefferson
Steve Jefferson
Developer Advocate
21 October 20261 min read

A YAML file is a plain text file that stores settings as a list of labels and values, using indentation instead of brackets to show what belongs inside what. You will meet it because almost every deployment pipeline, container setup and CI configuration is written in it, and because an AI coding agent will hand you one without explaining it. The file extension is .yml or .yaml, and both are the same format.

Here is one, complete:

yaml
name: Build and test
on:
  push:
    branches:
      - main
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - run: npm ci
      - run: npm test

Read it as a nested outline. jobs contains test, test contains runs-on and steps, and steps is a list because its entries start with a dash. That is the whole mental model.

Where YAML files live and what reads them

A YAML file does nothing on its own. Something has to look for it in a specific place. GitHub Actions is the clearest example: the workflow syntax documentation states that "you must store workflow files in the .github/workflows directory of your repository" and that they "must have either a .yml or .yaml file extension." Put the right file in the wrong folder and nothing runs, with no error, because nothing was looking there.

The same is true across tools. Docker Compose expects compose.yaml or docker-compose.yml in the project root. A deployment platform reads whatever name it documents. If an agent writes you a config and nothing changes, check the path before you check the contents.

Five things that break AI-written YAML

Models write YAML fluently and still trip on the same handful of rules, because YAML has opinions that look like typos.

1. Tabs are illegal

YAML uses spaces for indentation. A tab character is a parse error, not a style preference, and an editor that silently inserts tabs will produce a file that looks right and fails immediately. Two spaces per level is the common convention.

2. Indentation is structure, so one space changes meaning

yaml
# wrong: env is now a sibling of the job, not part of it
jobs:
  test:
    runs-on: ubuntu-latest
  env:
    NODE_ENV: test

Nothing here is invalid YAML. It parses cleanly into something you did not ask for. This is the most common class of agent mistake, and the only reliable defence is reading the nesting rather than the lines.

3. Unquoted values get guessed

YAML tries to infer types, and the inference surprises people. A bare yes, no, on and off can be read as booleans in older parsers. A version written as 1.10 becomes the number 1.1. A time written as 08:30 can parse as something other than a string. The famous case is a two-letter country code: unquoted NO for Norway has been read as the boolean false often enough that it has a nickname.

The fix is boring and total: quote anything that is meant to stay text.

yaml
country: "NO"
version: "1.10"
opening: "08:30"

4. Special characters need quoting, and escapes are doubled

Globs and expressions carry characters YAML also wants. GitHub's own examples quote branch patterns such as 'releases/**', quote cron strings such as '30 5 * * 1-5', and escape glob metacharacters with a backslash, which inside a double-quoted YAML string means writing "Build C\\+\\+" to match a literal name containing plus signs. When something refuses to match what you clearly typed, quoting is the first suspect.

5. Duplicate keys do not error, they overwrite

Two env: blocks at the same level are not a conflict. The last one wins, quietly. An agent editing a long file by appending is unusually good at creating this, and it is invisible in a diff that only shows the added lines.

A two-minute check before you commit

  • Does the file sit in the exact path the tool documents, with a .yml or .yaml extension?

  • Are there any tab characters? Search for them, do not eyeball them.

  • Does every value that is meant to be text have quotes around it?

  • Is each key nested where you intended, not one level out?

  • Does any key appear twice at the same level?

If you want a machine to answer those, most editors validate YAML as you type, and a schema-aware extension will flag an unknown key in a known file type. For a workflow or compose file, that catches more than careful reading does.

YAML next to the alternatives

Format

Comments

Trailing commas

Best at

YAML

Yes, with #

Not applicable

Hand-written configuration humans read

JSON

No

Rejected

Data moving between programs

TOML

Yes

Allowed

Flat configuration with few nesting levels

The practical consequence is that configuration tends to be YAML and payloads tend to be JSON. If you are not solid on the second one, what JSON is and how to fix it is the companion to this.

Why agents get this wrong more than they get code wrong

Broken code usually fails loudly. Broken YAML either fails at parse time with a line number, which is easy, or parses into valid nonsense, which is not. A key indented one level too far produces a working file that ignores your setting, and the symptom appears somewhere else entirely: a deploy that uses the wrong environment, a job that skips a step, a container with no volume mounted.

So the review habit differs. With code you ask whether it does the right thing. With YAML you ask whether the shape is right first, because a wrong shape is still a valid file. This is the same reason reviewing AI-generated code before shipping pays for itself, and the same reason worth keeping an eye on what an agent puts in your gitignore, where a single wrong line also fails silently.

Secrets are the one thing that should never be in a YAML file you commit. Configuration files reference a secret by name and let the platform supply the value, which is covered in environment variables and secrets in an AI-built app.

Frequently asked questions

Is .yml different from .yaml?

No. They are the same format, and tools generally accept both. Pick whichever the tool's documentation uses in its examples and stay consistent.

Why does my YAML file work locally and fail in CI?

Usually a path or a case difference. CI runners are typically Linux and case-sensitive, so Dockerfile and dockerfile are two different files there and one file on macOS or Windows.

Can I put a comment in a YAML file?

Yes. Anything after # on a line is ignored. This is a genuine advantage over JSON, and it is why configuration drifted to YAML in the first place.

How do I write a long string without breaking indentation?

Use a block scalar. | keeps the line breaks, > folds them into spaces. Both let you write multiple lines of text under one key without quoting each line.

For the wider context on tooling choices, see our guide to picking AI coding tools.

How did this land?

About the author

Steve Jefferson
Steve Jefferson

Developer Advocate

Steve builds something with Swarmz every week and writes up what worked, what broke, and what he'd do differently. Tutorials and hands-on guides are his lane.

Share

Get the next post in your inbox

One email a month. Product updates, engineering posts, and the best of Built with Swarmz.

I agree to receive emails about AI building tips and Swarmz product news. Unsubscribe any time.