Fix lỗi Ansible YAML Syntax Error: mapping values are not allowed in this context

beginner🔧 Ansible2026-03-18| Ansible 2.9+, Linux/macOS, bất kỳ file playbook hoặc inventory YAML nào

Error Message

ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each: YAML: mapping values are not allowed in this context
#ansible#yaml#cú pháp#thụt lề

TL;DR — Sửa nhanh

Chín trong mười trường hợp, lỗi này xuất phát từ một trong hai nguyên nhân:

  • Giá trị chuỗi chứa dấu hai chấm : mà không được đặt trong ngoặc kép
  • Ký tự tab lẫn vào phần thụt lề — YAML chỉ chấp nhận dấu cách

Ba bước để khắc phục:

  • Đặt mọi giá trị chứa : trong dấu ngoặc kép: msg: "Error: connection failed"
  • Thay thế toàn bộ tab bằng thụt lề 2 dấu cách
  • Chạy ansible-playbook --syntax-check playbook.yml để xác nhận

Lỗi đầy đủ

ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each:
JSON: Expecting value: line 1 column 1 (char 0)
YAML: mapping values are not allowed in this context
  in "<unicode string>", line 12, column 18

Số dòng và số cột trong thông báo lỗi là manh mối nhanh nhất bạn có. Hãy nhảy thẳng đến đó trước tiên — đừng cuộn file và đoán mò.

Nguyên nhân gốc rễ

1. Dấu hai chấm không được đặt trong ngoặc kép trong giá trị chuỗi (phổ biến nhất)

YAML hiểu : là ký tự phân tách key-value. Nếu bạn để dấu hai chấm trong chuỗi mà không có ngoặc kép, trình phân tích sẽ đọc nó như một key mới — và mọi thứ phía sau sẽ bị hỏng.

# SAI — YAML hiểu "Error" là một key
- name: Show error
  debug:
    msg: Error: connection timed out

# ĐÚNG — đặt trong ngoặc kép
- name: Show error
  debug:
    msg: "Error: connection timed out"

URL cũng gặp vấn đề tương tự:

# SAI
  url: https://example.com/api

# ĐÚNG
  url: "https://example.com/api"

2. Lẫn lộn tab và dấu cách

YAML nghiêm cấm dùng tab để thụt lề. Chỉ cần một ký tự tab lạc vào — ví dụ khi dán code từ Slack hoặc PDF — là trình phân tích sẽ thất bại. Tệ hơn, nó thường chỉ sai số dòng.

# Hiển thị ký tự ẩn trong vim
:set list

# Hoặc dùng cat -A — tab hiển thị dạng ^I
cat -A playbook.yml | grep "\^I"

3. Mức thụt lề sai

Ansible yêu cầu thụt lề 2 dấu cách nhất quán xuyên suốt. Nếu bạn trộn lẫn block thụt lề 2 và 4 dấu cách trong cùng một file, lỗi này sẽ xuất hiện.

# SAI — thụt lề không đồng nhất
- name: Install nginx
  apt:
    name: nginx
      state: present   # thừa 2 dấu cách làm hỏng cấu trúc

# ĐÚNG
- name: Install nginx
  apt:
    name: nginx
    state: present

4. Ký tự đặc biệt trong giá trị không được đặt trong ngoặc kép

Không chỉ dấu hai chấm. Bất kỳ ký tự nào sau đây đều có thể gây lỗi khi để trần: : { } [ ] , & * # ? | - < > = ! % @ \

# SAI
  shell: echo hello && exit 0

# ĐÚNG — đặt trong ngoặc kép
  shell: "echo hello && exit 0"

# Hoặc dùng literal block scalar
  shell: |
    echo hello && exit 0

Cách tìm và khắc phục vấn đề

Bước 1 — Chạy kiểm tra cú pháp trước

ansible-playbook --syntax-check playbook.yml

Lệnh này sẽ xuất ra số dòng chính xác. Hãy dùng nó. Đừng nhìn chằm chằm vào file và hy vọng tìm ra vấn đề.

Bước 2 — Lấy phản hồi chi tiết với yamllint

# Cài đặt
pip install yamllint

# Kiểm tra file
yamllint playbook.yml

# Cấu hình thân thiện với Ansible, nới lỏng giới hạn độ dài dòng
yamllint -d "{extends: default, rules: {line-length: {max: 120}}}" playbook.yml

Chỉ một lần chạy yamllint là có thể phát hiện tab, thụt lề sai và ký tự đặc biệt không được đặt trong ngoặc kép cùng một lúc. Nhanh hơn nhiều so với sửa từng lỗi một.

Bước 3 — Tìm và xóa tab

# Tìm tab — grep -Pn dùng Perl regex cho \t
grep -Pn "\t" playbook.yml

# Thay tab bằng 2 dấu cách trực tiếp trong file
sed -i 's/\t/  /g' playbook.yml

# Trong vim: chuyển tab thành dấu cách tự động
:set expandtab tabstop=2
:%retab

Bước 4 — Xác nhận đã sửa xong

ansible-playbook --syntax-check playbook.yml

# Kết quả sạch trông như thế này:
playbook: playbook.yml

Các mẫu phổ biến làm hỏng YAML

Mẫu 1 — Dấu hai chấm trong điều kiện when

# SAI — ": true" ở cuối không hợp lệ ở đây
  when: ansible_os_family == "Debian": true

# ĐÚNG — điều kiện tự đánh giá là true
  when: ansible_os_family == "Debian"

Mẫu 2 — Chuỗi nhiều dòng chứa dấu hai chấm

# SAI — dấu hai chấm ở dòng tiếp theo làm rối trình phân tích
  msg: This is a message
       with: a colon midway

# ĐÚNG — dùng literal block scalar
  msg: |
    This is a message
    with: a colon midway

Mẫu 3 — Cú pháp sai trong bộ lọc default của Jinja2

# SAI — bộ lọc default không dùng dấu hai chấm
  msg: "{{ my_var | default: 'fallback' }}"

# ĐÚNG — dùng = hoặc truyền giá trị như một đối số
  msg: "{{ my_var | default('fallback') }}"

Mẹo hay

Khi debug một playbook phức tạp liên tục báo lỗi YAML, tôi hay dán đoạn code lỗi vào YAML ↔ JSON Converter trên ToolCraft. Công cụ này chuyển đổi YAML sang JSON theo thời gian thực, giúp bạn ngay lập tức thấy trình phân tích gặp lỗi ở đâu — không cần chạy Ansible nhiều lần. Mọi thứ đều xử lý trên trình duyệt, không có gì được tải lên.

Nó cũng hoạt động ngược lại: nếu ai đó gửi cho bạn một file cấu hình JSON và bạn cần đưa vào playbook, chuyển đổi sang YAML là xong — thụt lề đã đúng sẵn.

Phòng tránh

  • Cài đặt editor: Đặt thụt lề là 2 dấu cách, bật "hiển thị ký tự ẩn" để phát hiện tab trước khi gây rắc rối, và bật hỗ trợ ngôn ngữ YAML
  • VS Code: Cài extension "YAML" của Red Hat — nó kiểm tra playbook khi lưu và gạch chân các vấn đề ngay trong editor
  • Thêm yamllint vào CI: Chỉ một dòng trong pipeline (yamllint .) là đủ để phát hiện lỗi cú pháp trước khi Ansible chạy
  • Commit file cấu hình .yamllint vào thư mục gốc của repo để mọi thành viên trong nhóm đều được kiểm tra theo cùng một bộ quy tắc

Tham khảo nhanh

# Luôn đặt trong ngoặc kép các mẫu sau:
msg: "Error: something failed"       # dấu hai chấm trong giá trị
url: "https://example.com"           # URL
cmd: "echo foo && bar"               # ký tự shell đặc biệt
regexp: "^\\d+: "                    # regex có dấu hai chấm

# Dùng block scalar cho nội dung nhiều dòng:
script: |
  #!/bin/bash
  echo "Running: $1"
  exit 0

Related Error Notes