YAML Cheatsheet
Multiline Strings
Use this YAML reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
The two block styles and three chomping modes
A block scalar starts with an indicator on the key's line, then an indented block. The indicator is one style character plus an optional chomping character.
| Style | Newlines inside |
|---|---|
| literal | kept exactly as written |
> folded | single newlines become spaces, blank lines become newlines |
| Chomping | Trailing newlines |
|---|---|
| (none) clip | exactly one \n at the end |
- strip | no trailing \n |
+ keep | every trailing blank line kept |
That is six combinations: |, |-, |+, >, >-, >+.
The complete matrix
One source block, run through all six. Everything below was parsed with PyYAML 6.0, not recalled. The source, with a deliberate blank line inside and a trailing blank line:
s: | line one line two line four
Results, written as unambiguous string literals so trailing newlines are visible:
| Indicator | Exact resulting string |
|---|---|
| | "line one\nline two\n\nline four\n" |
|- | "line one\nline two\n\nline four" |
|+ | "line one\nline two\n\nline four\n\n" |
> | "line one line two\nline four\n" |
>- | "line one line two\nline four" |
>+ | "line one line two\nline four\n\n" |
Read as text, | gives four lines and > gives two:
| -> line one
line two
<blank>
line four
<one trailing newline>
> -> line one line two
line four
<one trailing newline>The blank line is what survives folding. > joins line one and line two with
a space because they are consecutive non-blank lines, then the blank line becomes
the single \n separating them from line four.
Folding in detail
| Source | Folded result |
|---|---|
a b c | "a b c\n" |
a · blank · b | "a\nb\n" |
a · blank · blank · b | "a\n\nb\n" |
a b c d deeper back | "a b c d\n deeper\nback\n" |
A more-indented line is not folded. That is how you keep a code block inside a folded scalar. Note the leading spaces survive.
description: >
Normal prose folds onto
one long line.
this indented line
stays on its own lines
And prose resumes.Two things bite here. Trailing whitespace on a line inside a > block is
preserved and then the fold space is added, so a followed by b folds to
"a b" with four spaces. Strip trailing whitespace before committing. And a
line that folds is one long line to whatever consumes it, so a > block is wrong
for anything line-oriented (a shell script, a certificate, a CSV).
Which one to use
| Use case | Indicator |
|---|---|
| shell script, Dockerfile RUN, SQL | | |
| PEM certificate or key | | |
| commit-message style prose | > |
| a long single-line value wrapped for readability | >- |
| a value that must not end in a newline | |- or >- |
| a value whose exact trailing blank lines matter | |+ |
Default to | for anything you would paste into a terminal, and >- for a long
sentence you are only wrapping to fit the column.
command: | set -euo pipefail echo "starting" exec ./server --port 8080 summary: >- A single long sentence that happens to be wrapped in the source file and arrives as one line with no trailing newline.
The indentation indicator
Indentation is normally inferred from the first non-empty line of the block. Two cases break that, and both are fixed with an explicit digit after the style character.
Case 1, the content starts with spaces you want to keep.
s: |2
keeps two spacesContent is indented four, the indicator says the block indent is two, so the
result is " keeps two spaces\n". Without the 2 the first line sets the indent
and you get "keeps two spaces\n".
Case 2, the first line is more indented than the rest. This is a hard parse error, not a silent reinterpretation:
s: | three spaces two spaces
fails with a ParserError. Add |2 and it parses to " three spaces\ntwo
spaces\n".
The digit is 1-9 and counts from the parent node's indentation, not from column zero.
Details worth knowing
- A comment may follow the indicator on the same line: s: | # note is legal and
the comment is discarded.
- An empty block (s: | with nothing under it) is the empty string "", not
null.
- The block ends at the first line indented less than the block indent, so a
following sibling key just works. No terminator is needed.
- |+ at end of file keeps only the newlines actually present, so
s: |+ with one line gives "a\n", the same as |.
- Tabs inside the block content are fine. Tabs in the block indentation
are not, same as everywhere else in YAML.
- A block scalar cannot appear in flow style. {msg: | is a scan error, so a
multi-line value forces block style or the double-quoted "a\nb" form.