MYMONDAY.ai
서비스스튜디오도구데이터·포맷73CSS 생성기19색상·이미지10인코딩·보안10웹·SEO11개발·데브옵스10파일·내보내기18계산기6가이드

8분 읽기 · 마지막 업데이트

YAML 문법 주의점: Norway 문제, yes/no 불리언, 8진수, 탭과 들여쓰기 오류

YAML은 평범한 텍스트처럼 보여서 오히려 사고가 납니다. 같은 글자를 다르게 읽는 두 버전과, 줄에 따라 조용히 또는 시끄럽게 실패하는 들여쓰기 규칙이 대부분의 함정입니다.

한 언어, 두 가지 버전

YAML 1.1은 2005년에, YAML 1.2는 2009년에 나왔고, 2021년에 정오표를 반영한 1.2.2가 나왔습니다. 1.2는 YAML을 JSON의 상위 집합으로 만들고 암묵적 변환의 수를 줄였습니다. 따옴표 없는 단어를 불리언, 숫자, 날짜 중 무엇으로 읽을지는 스키마가 정합니다. 1.2의 코어 스키마는 일부러 작게 만들어져 있습니다. 1.1에는 불리언의 여러 표기, 60진수, 타임스탬프, 병합 키까지 더 많은 타입이 있습니다.

파서마다 다르고, 파일은 어느 버전을 기대하는지 알려 주지 않습니다. PyYAML은 YAML 1.1을 구현합니다. js-yaml 4는 기본으로 1.2 코어 스키마를 씁니다. 이 사이트가 쓰는 JavaScript용 yaml 패키지는 기본이 1.2이고 1.1 옵션이 따로 있습니다. 다른 파서는 추측하지 말고 문서로 확인하세요. 같은 파일이 도구마다 다른 데이터가 될 수 있습니다.

이 사이트의 YAML 도구는 yaml 라이브러리의 parseAllDocuments를 버전 옵션 없이 호출하므로 1.2 코어 스키마로 읽습니다. 1.1 기능 하나는 일부러 켜 두었습니다. 병합 키(<<: *base)를 펼칩니다. 아래의 파싱 결과는 모두 그 코드(tools/yamlscope/lib/yaml.ts)를 실제로 실행해 얻은 값입니다. 1.1 결과는 같은 라이브러리에 버전 옵션을 1.1로 준 것이며, 읽기용으로는 도구에서 노출하지 않는 옵션입니다.

Norway 문제: yes, no, on, off

YAML 1.1에서는 따옴표 없는 yes, no, on, off와 그 대소문자 변형이 불리언입니다. 그래서 ISO 국가 코드 목록에 숨은 버그가 생깁니다. 노르웨이인 NO가 false로 읽히기 때문입니다. CI 파일에서 on이라는 키 이름이나 외톨이 y, n도 마찬가지입니다. 1.2 코어 스키마는 true, false와 그 대소문자 변형만 불리언으로 인식하므로 이런 단어는 문자열로 남습니다.

입력:    a: yes
         b: No
         c: on
         g: y
         country: NO

이 사이트(1.2 코어): {"a":"yes","b":"No","c":"on","g":"y","country":"NO"}
같은 라이브러리, 1.1: {"a":true,"b":false,"c":true,"g":true,"country":false}

의미가 바뀌는 숫자: 8진수, 60진수, 버전, 날짜

앞자리 0이 대표적입니다. YAML 1.1에서 0755는 8진수로 493이며, 그래서 일부 도구에서 파일 권한이 제대로 동작합니다. 1.2 코어 스키마는 10진수 755로 읽고, 8진수는 0o 접두사로 옮겼습니다. 어느 쪽도 틀리지 않았고 파일이 모호한 것입니다. 0o755는 1.2에서 493이고 1.1에서는 평범한 문자열입니다.

60진수도 1.1의 함정입니다. 1:30은 정수 90이고 12:30:45는 45045입니다. 시각, 22:22 같은 포트 매핑, 비율이 조용히 숫자로 바뀝니다. 1.2에서는 문자열로 남습니다. 타임스탬프도 같습니다. 2026-10-01은 1.1에서는 날짜 객체이고 1.2 코어 스키마에서는 문자열입니다.

가장 조용한 것은 버전 번호입니다. v: 1.10은 어느 버전에서나 실수이고 값은 1.1이라 끝의 0이 사라집니다. 버전 번호는 '1.10'처럼, CI 매트릭스의 파이썬 버전은 "3.10"처럼 따옴표를 붙이세요. 수량이 아닌 점 포함 값은 모두 같습니다. 3.10.1은 점이 둘이라 문자열로 남습니다. 마지막으로 2^53을 넘는 정수는 JavaScript에서 정밀도를 잃습니다. 이 사이트의 리더는 12345678901234567890을 반올림하지 않고 텍스트로 두며 알림을 표시합니다.

YAML 텍스트1.2 코어(이 사이트)1.1 규칙
mode: 0755755493
mode: 0o755493문자열 0o755
t: 1:30문자열 1:3090
t: 12:30:45문자열 12:30:4545045
v: 1.101.11.1
d: 2026-10-01문자열 2026-10-01타임스탬프
v: '1.10'문자열 1.10문자열 1.10

탭은 들여쓰기가 아니다

YAML 들여쓰기는 공백만 허용합니다. 줄 맨 앞의 탭은 오류이며, 1.1과 1.2에서 동일합니다. 편집기가 공백을 탭으로 바꾸거나, 웹 페이지에서 복사한 텍스트에 탭이 섞여 있을 때 가장 자주 생깁니다.

라이브러리는 줄과 열을 알려 줍니다. 아래 입력에서 도구는 2행 1열에 Tabs are not allowed as indentation(코드 TAB_AS_INDENT)을 보고합니다. 해결은 편집기가 .yaml 파일에서 공백을 넣도록 설정하는 것입니다. 키와 콜론 뒤, 줄 중간에 있는 탭은 합법적인 구분자입니다.

a:
<TAB>b: 1

오류: TAB_AS_INDENT, 2행 1열

들여쓰기 오류와 리스트 항목의 함정

한 매핑 안의 키는 모두 같은 열에서 시작해야 합니다. 한 칸만 어긋나도 엉뚱한 키가 있는 줄에서 All mapping items must start at the same column이라는 BAD_INDENT가 납니다. 항목 위치가 맞지 않는 시퀀스도 같습니다. steps: 아래 항목 두 개는 공백 두 칸, 세 번째는 세 칸일 때 도구는 4행 4열에 All sequence items must start at the same column을 보고합니다.

- 표시는 더 까다롭습니다. 뒤에 오는 내용도 들여쓰기 수준을 정하기 때문입니다. - name: web과 그 아래 port: 80은 port가 name과 열이 맞으므로 한 객체입니다. 공백 두 칸을 지우면 오류 없이 구조가 바뀝니다.

  • 리스트는 부모 키와 같은 열에 둘 수 있습니다(items: 다음 줄에 1열의 - a). 유효하고 쿠버네티스 파일에서 흔하므로 오류로 오해하지 마세요.
  • - name: a 다음 줄을 run: b처럼 공백 세 칸으로 쓰면 Nested mappings are not allowed in compact mappings로 실패합니다.
  • - name: a 아래에 1열의 run: b를 쓰면 Unexpected scalar at node end로 실패합니다.
  • key: 다음 줄에 같은 열의 키를 쓰면 실패하지 않습니다. key:\nvalue: 1은 {"key":null,"value":1}입니다. 들여쓰기가 빠지면 값이 null이 됩니다.
- name: web
  port: 80
=> [{"name":"web","port":80}]

- name: web
- port: 80
=> [{"name":"web"},{"port":80}]

블록 스칼라: |, > 와 chomping

블록 스칼라는 여러 줄 텍스트를 담습니다. |(리터럴)는 줄바꿈을 그대로 둡니다. >(폴딩)는 이어지는 줄을 공백으로 잇고, 빈 줄은 줄바꿈이 됩니다. 뒤에 붙는 지시자는 끝의 줄바꿈을 정하며 이를 chomping이라고 합니다. 지시자가 없으면(clip) 줄바꿈을 정확히 하나 남기고, -(strip)는 모두 지우며, +(keep)는 뒤따르는 빈 줄까지 모두 남깁니다.

|2처럼 지시자 뒤에 숫자를 쓰면 들여쓰기 폭을 명시합니다. 첫 줄이 텍스트에 속한 공백으로 시작할 때 필요합니다. 아래는 사이트의 파서에 아래 입력을 넣어 얻은 정확한 결과입니다.

lit: |
  a
  b

fold: >
  a
  b

  c
strip: |-
  a
  b

keep: |+
  a
  b

last: x

=> lit:   "a\nb\n"
   fold:  "a b\nc\n"
   strip: "a\nb"
   keep:  "a\nb\n\n"

문자열에 따옴표가 꼭 필요한 경우

따옴표 없는 스칼라는 특정 문자로 시작할 수 없고 특정 문자열을 포함할 수 없습니다. 값이 예약 문자인 @나 백틱으로 시작하면 따옴표를 붙이세요. 맨 앞의 *는 별칭, &는 앵커, !는 태그의 시작입니다. 값 안에 : (콜론과 공백)나 #(공백과 해시)가 있어도 붙여야 합니다. 글자에 바로 붙은 #은 값의 일부입니다. b: x#notcomment는 해시가 남지만 a: x #comment는 주석이 사라집니다.

위에서 본 스키마 변환 대상도 붙이세요. yes, no, NO, null, ~, 0755, 1:30, 1.10, 날짜입니다. 작은따옴표는 내용을 그대로 담고 안의 작은따옴표는 두 번 씁니다('it''s'). 큰따옴표는 \t, \n 같은 이스케이프를 처리하므로 윈도우 경로를 큰따옴표로 감싸면 백슬래시를 두 번 써야 합니다. YAML을 생성하는 도구는 이를 알아서 처리합니다. 이 사이트의 JSON to YAML 도구에는 1.1 파서가 잘못 읽을 단어에 따옴표를 붙이는 스위치가 있어서 country: NO가 country: "NO"로 나옵니다.

입력이 사이트 파서의 결과
a: @foo오류 BAD_SCALAR_START: Plain value cannot start with reserved character @
a: foo오류 BAD_SCALAR_START, 같은 예약 문자 메시지
a: *foo오류 BAD_ALIAS: unknown anchor foo
msg: hello: world오류 BLOCK_AS_IMPLICIT_KEY: Nested mappings are not allowed in compact mappings
a: &foo{"a":null}, 값이 없는 앵커
a: !foo bar{"a":"bar"}, !foo는 텍스트가 아니라 태그로 읽힘
f: "x: y"{"f":"x: y"}
g: 'a #b'{"g":"a #b"}

앵커, 별칭, 병합 키

앵커(&name)는 노드에 이름을 붙이고 별칭(*name)은 그것을 재사용합니다. 이는 YAML 1.1과 1.2 모두에 있습니다. 병합 키 <<는 다릅니다. yaml.org의 별도 1.1 타입(merge type)에서 온 것이고 1.2 명세에는 없습니다. 많은 라이브러리가 확장으로 지원하기는 합니다. 그래서 <<에 기대는 Compose나 CI 파일이 엄격한 1.2 리더에서는 실패할 수 있습니다.

이 사이트의 리더는 병합 키를 기본으로 펼치므로 아래 소스에서 child는 base의 x와 자기 자신의 y를 갖습니다. 명시한 키가 병합된 키보다 우선합니다. 버전이 섞이면 고약한 일도 생깁니다. 같은 라이브러리의 1.1 모드에서는 y라는 키가 불리언 true로 읽혀서 {"x":1,"y":2}가 아니라 {"x":1,"true":2}가 나왔습니다.

base: &b
  x: 1
  y: 2
child:
  <<: *b
  y: 9

=> {"base":{"x":1,"y":2},"child":{"x":1,"y":9}}

여러 문서와 JSON 상위 집합

---가 있는 줄은 새 문서를 시작하고 ...는 문서를 끝냅니다. 한 파일에 문서가 여러 개 들어갈 수 있으며 kubectl 매니페스트를 묶는 방식이 이것입니다. a: 1, ---, b: 2는 이 사이트의 도구에서 기본으로 배열 [{"a":1},{"b":2}]가 됩니다. 단일 문서 파싱 호출은 이런 파일을 거부하므로(라이브러리는 MULTIPLE_DOCS를 보고합니다) 쓰는 로더가 어떻게 동작하는지 확인하세요. 파일 끝의 닫는 ---는 빈 문서가 아니라 종결 표시로 취급합니다.

유효한 JSON은 유효한 YAML 1.2이기도 하므로 {"a": [1, 2, {"b": null}], "c": "d"}는 그대로 파싱됩니다. 반대는 성립하지 않습니다. YAML에는 주석, 앵커, 여러 줄 텍스트, 여러 문서가 있고 JSON은 이를 표현할 수 없습니다. 중복 키도 다릅니다. JSON 파서는 반복된 키를 제각각 처리하지만 YAML은 키가 유일해야 하며, 이 사이트의 리더는 a: 1 다음에 a: 2가 오면 2행 1열에서 DUPLICATE_KEY로 실패합니다.

파일을 점검하려면 YAML to JSON 도구에 붙여 넣으세요. 병합 키가 펼쳐진 상태로 1.2 소비자가 받게 될 값을 볼 수 있습니다. YAML Formatter는 주석과 따옴표를 유지하고, 오류의 줄과 열을 보여 주며, 공백 2칸 또는 4칸으로 들여쓰기를 다시 맞춥니다.

직접 해보기