Sửa lỗi "This block contains unexpected or invalid content" trong Gutenberg

intermediate📝 WordPress2026-06-11| WordPress 5.0+, trình soạn thảo block Gutenberg, mọi stack PHP/MySQL (Nginx hoặc Apache)

Error Message

This block contains unexpected or invalid content
#gutenberg#trình-soạn-thảo-block#wordpress-ui#lỗi-validation

Lỗi gặp phải

Bạn mở một bài viết trong Gutenberg và thấy một banner màu xám trên một hoặc nhiều block:

This block contains unexpected or invalid content

Hai nút xuất hiện: Attempt Block RecoveryConvert to HTML. Bạn nhấn "Attempt Block Recovery." Không có gì xảy ra — hoặc nội dung biến mất. Đây là cách lấy lại nội dung đó.

Nguyên nhân

Gutenberg lưu trữ các block dưới dạng comment HTML: các dấu phân cách <!-- wp:paragraph --> kèm theo thuộc tính JSON nhúng bên trong. Mỗi lần tải trang, nó xác thực markup đã lưu so với schema đã đăng ký của từng block. Bất kỳ sự không khớp nào cũng sẽ gây ra lỗi này.

Sáu nguyên nhân phổ biến:

  • Một plugin hoặc theme cập nhật đã thay đổi định dạng đầu ra của block. Markup cũ đã lưu không còn hợp lệ với schema mới.
  • Nội dung được ghi trực tiếp vào cột post_content qua SQL thuần hoặc wpdb->update(), làm hỏng các dấu phân cách comment của block.
  • Một PHP notice hoặc warning đã in ra output trước <!-- wp:blockname -->, làm hỏng chuỗi phân cách.
  • Sao chép từ Word hoặc Google Docs đã đưa vào markup không chuẩn — dấu nháy cong, &nbsp;, hoặc các div bọc thêm — làm phá vỡ quá trình phân tích block.
  • Bundle JavaScript của block chưa được tải (thiếu đăng ký hook enqueue_block_editor_assets), khiến Gutenberg không nhận ra loại block.
  • Lệnh wp_update_post() của một plugin đã mã hóa kép các dấu comment block, biến <!-- thành &lt;!--.

Bước 1 — Tìm block bị lỗi

Trước khi nhấn bất kỳ nút phục hồi nào, hãy chuyển sang chế độ Code Editor: Ctrl+Shift+Alt+M (hoặc menu ⋮ → Code editor). Bạn sẽ thấy markup block thô. Tìm các dấu hiệu hỏng sau:

<!-- wp:paragraph -->
<p>Normal content</p>
<!-- /wp:paragraph -->

<!-- wp:columns {"someProp":"value"} -->   <!-- ← bị lỗi nếu plugin thay đổi schema -->
<div class="wp-block-columns">...</div>
<!-- /wp:columns -->

Dấu hiệu đáng lo ngại: thẻ mở/đóng không khớp, HTML entities như &lt;!-- thay vì <!--, văn bản lỗi PHP lạc trước dấu block, hoặc tên loại block không còn tồn tại sau khi một plugin bị gỡ bỏ.

Bước 2 — Thử "Attempt Block Recovery" trước

Nhấn ba chấm (⋮) trên block bị lỗi → Attempt Block Recovery. Gutenberg sẽ viết lại dấu phân cách và xác thực lại các thuộc tính. Với những sai lệch schema nhỏ sau khi cập nhật plugin, cách này thường hoạt động. Nội dung trở lại, bạn lưu là xong.

Nếu quá trình phục hồi xóa mất nội dung — hãy nhấn Ctrl+Z ngay lập tức, trước khi lưu. Lịch sử hoàn tác vẫn còn sau khi thử phục hồi block.

Bước 3 — Convert to HTML (phương án dự phòng an toàn)

Phục hồi không thành công? Chọn Convert to HTML. Thao tác này bọc markup thô trong một block wp:html, mà Gutenberg lưu nguyên vẹn không qua xác thực schema. Bài viết hiển thị đúng ở frontend. Bạn mất tính tương tác của block — tay cầm kéo thả cột, đồng bộ reusable block — nhưng không có gì bị xóa.

<!-- wp:html -->
<div class="wp-block-columns">
  <div class="wp-block-column">...</div>
</div>
<!-- /wp:html -->

Coi đây là giải pháp tạm thời cho site đang chạy thực tế. Hãy xây dựng lại block đúng cách sau khi đã tìm ra nguyên nhân gốc rễ.

Bước 4 — Sửa các dấu phân cách bị hỏng trong cơ sở dữ liệu

Khi một bản cập nhật plugin làm hỏng cấu trúc thuộc tính block trên nhiều bài viết, hãy dùng WP-CLI thay vì chỉnh sửa từng bài một:

# Xem nội dung bài viết thô
wp post get 123 --field=post_content

# Xuất ra file, chỉnh sửa, rồi đẩy lại
wp post get 123 --field=post_content > /tmp/post123.html
# Chỉnh sửa /tmp/post123.html — sửa markup block
wp post update 123 --post_content="$(cat /tmp/post123.html)"

Nếu một plugin đổi tên loại block — ví dụ wp:old-plugin/cardwp:new-plugin/card — hãy thực hiện search-replace có mục tiêu. Luôn chạy dry-run trước:

# Dry run — hiển thị những gì sẽ thay đổi, không động vào dữ liệu
wp search-replace '<!-- wp:old-plugin/card' '<!-- wp:new-plugin/card' --all-tables --dry-run

# Kết quả đúng? Bỏ --dry-run
wp search-replace '<!-- wp:old-plugin/card' '<!-- wp:new-plugin/card' --all-tables
wp search-replace '<!-- /wp:old-plugin/card' '<!-- /wp:new-plugin/card' --all-tables

Bước 5 — Tìm lỗi PHP làm ô nhiễm đầu ra block

Một thủ phạm khó phát hiện: một plugin in ra PHP notice hoặc warning trước phản hồi REST API. Gutenberg nhận JSON có văn bản lạ được thêm vào đầu, không thể phân tích cú pháp, và đánh dấu block là không hợp lệ khi tải lại.

# Theo dõi error log trong khi lưu bài viết
tail -f /var/log/nginx/error.log | grep -i 'php\|notice\|warning'

# Hoặc bật debug logging trong wp-config.php
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);

Thấy các mục Notice: Undefined variable có timestamp trùng đúng lúc bạn lưu bài viết? Đó là thủ phạm. Hãy sửa plugin gây lỗi. Giải pháp tạm thời cho môi trường production:

error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);

Bước 6 — Đăng ký lại các loại block bị thiếu

Tắt một plugin sẽ xóa các đăng ký block của nó. Gutenberg sẽ đánh dấu tất cả các block đó là không hợp lệ. Bật lại plugin là khắc phục được ngay.

Muốn gỡ plugin vĩnh viễn? Hãy chuyển đổi tất cả block của nó sang HTML (Bước 3) trước khi tắt. Tìm các bài viết bị ảnh hưởng trước:

wp db query "SELECT ID, post_title FROM wp_posts WHERE post_content LIKE '%wp:removed-plugin%' AND post_status != 'auto-draft';"

Xác minh bản sửa lỗi

  • Mở bài viết trong Gutenberg — không còn banner màu xám nào xuất hiện.
  • Chuyển sang chế độ Code Editor. Xác nhận mỗi <!-- wp:blockname --> đều có <!-- /wp:blockname --> tương ứng.
  • Lưu, rồi hard-refresh bằng Ctrl+Shift+R. Gutenberg sẽ xác thực lại tất cả block khi tải.
  • Xem bài viết ở frontend — nội dung phải hiển thị đúng.
  • Chạy wp post get <ID> --field=post_content và kiểm tra ký tự lạc trước các dấu block.

Ngăn lỗi tái diễn

  • Trước khi cập nhật bất kỳ plugin block nào: snapshot cơ sở dữ liệu — wp db export backup_$(date +%Y%m%d).sql. Chỉ mất khoảng 10 giây và có thể tiết kiệm hàng giờ phục hồi.
  • Plugin block nên đi kèm mảng deprecated trong đăng ký block để Gutenberg tự động chuyển đổi markup cũ. Nếu một bản cập nhật làm hỏng block mà không cung cấp deprecation, đó là bug — hãy báo cáo.
  • Không bao giờ chỉnh sửa post_content trực tiếp qua SQL thuần. Hãy dùng wp_update_post() và xác minh nội dung trả về vẫn còn nguyên các dấu phân cách block.
  • Kiểm tra cập nhật plugin trên môi trường staging trước. Một môi trường staging với nội dung production gần đây sẽ phát hiện lỗi xác thực trước khi người dùng thực thấy chúng.

Related Error Notes