Sửa lỗi ERROR 3140: Văn bản JSON không hợp lệ trong cột JSON của MySQL 5.7+

intermediate🗄️ MySQL2026-05-24| MySQL 5.7, 8.0, 8.4+, MariaDB 10.2+; mọi hệ điều hành (Ubuntu, CentOS, Windows, Docker)

Error Message

ERROR 3140 (22032): Invalid JSON text: "Invalid value." in value for column 'meta' at row 1
#mysql#json#mysql-5.7#data-type#validation

Vấn đề

MySQL 5.7 đã giới thiệu kiểu dữ liệu JSON gốc, mang lại khả năng xác thực tự động và tra cứu nhanh hơn. Nhưng quá trình xác thực đó cực kỳ khắt khe. Nếu dữ liệu của bạn không tuân thủ chính xác RFC 7159, MySQL sẽ dừng hoạt động ngay lập tức. Bạn sẽ gặp phải thông báo lỗi trực diện này:

ERROR 3140 (22032): Invalid JSON text: "Invalid value." in value for column 'meta' at row 1

Điều này thường xảy ra trong quá trình di chuyển dữ liệu từ các cột TEXT sang JSON, hoặc khi một dịch vụ backend gửi một chuỗi sai định dạng nhẹ mà cơ sở dữ liệu của bạn không thể chấp nhận.

Tại sao MySQL từ chối dữ liệu của bạn?

Mỗi khi bạn ghi vào một cột JSON, trình phân tích cú pháp nội bộ của MySQL sẽ quét đầu vào theo từng byte. Nếu nó gặp một ký tự không mong đợi, nó sẽ dừng lại. Trong môi trường production, tôi thường thấy 5 thủ phạm sau đây nhất:

  • Dấu nháy đơn: JSON bắt buộc sử dụng dấu nháy kép ("). Mặc dù {'id': 1} là JavaScript hợp lệ, nhưng nó là JSON không hợp lệ.
  • Dấu phẩy dư (Trailing commas): Một dấu phẩy thừa duy nhất ở cuối danh sách, chẳng hạn như [10, 20, 30,], sẽ làm hỏng trình phân tích cú pháp.
  • Chuỗi rỗng: Một chuỗi trống '' không phải là JSON hợp lệ. Bạn phải sử dụng null hoặc một đối tượng trống {} để thay thế.
  • Các ký tự điều khiển không được thoát chuỗi: Các phím Tab ẩn hoặc ký tự xuống dòng thực tế bên trong một giá trị chuỗi sẽ gây ra lỗi. Chúng phải được thoát chuỗi thành \t hoặc \n.
  • Dấu ngoặc kép thông minh: Sao chép-dán từ Word hoặc Slack thường đưa vào các dấu ngoặc "cong" (“ ”). MySQL chỉ nhận diện các dấu ngoặc thẳng tiêu chuẩn (" ").

Cách khắc phục nhanh: Xác định cú pháp không hợp lệ

Đừng đoán xem lỗi nằm ở đâu. Trước khi cập nhật mã nguồn ứng dụng, hãy kiểm tra truy vấn thô của bạn bằng hàm JSON_VALID() của MySQL. Nó trả về 1 cho dữ liệu hợp lệ và 0 nếu có lỗi.

-- Kiểm tra điều này trong SQL client của bạn
SELECT JSON_VALID('{ "status": "active", "tags": ["web", "prod",] }'); 
-- Kết quả: 0 (Dấu phẩy dư sau "prod" là nguyên nhân chính)

Nếu bạn nhận được 0, cú pháp đã bị hỏng. Nếu bạn nhận được 1 nhưng vẫn thấy lỗi, hãy kiểm tra mã hóa ký tự (character encoding); trình phân tích cú pháp có thể đang vấp phải một ký tự đa byte mà nó không nhận diện được.

Giải pháp lâu dài

1. Để MySQL tự xây dựng JSON

Thay vì ghép các chuỗi JSON thủ công trong ứng dụng—nơi khởi nguồn của 90% lỗi dấu ngoặc—hãy để MySQL xử lý các tác vụ nặng nề bằng hàm JSON_OBJECT hoặc JSON_ARRAY.

INSERT INTO users (meta) 
VALUES (JSON_OBJECT("last_login", NOW(), "ip", "192.168.1.1"));

2. Làm sạch các giá trị rỗng

Nếu logic ứng dụng của bạn thỉnh thoảng gửi một chuỗi rỗng, hãy chặn nó lại. Một cột JSON có thể để NULL, nhưng nó không thể là ''. Đảm bảo SQL driver của bạn chuyển đổi các đầu vào trống thành một giá trị mặc định phù hợp.

-- Lệnh này sẽ thất bại:
UPDATE settings SET config = '' WHERE id = 1;

-- Thay vào đó hãy làm thế này:
UPDATE settings SET config = '{}' WHERE id = 1;

3. Tiêu chuẩn hóa mã hóa Backend

Không bao giờ định dạng chuỗi JSON thủ công ở backend. Sử dụng các hàm gốc như json_encode() trong PHP, json.dumps() trong Python, hoặc JSON.stringify() trong Node.js. Các thư viện này được xây dựng để tuân thủ các tiêu chuẩn RFC và sẽ tự động thoát chuỗi các ký tự đặc biệt cho bạn.

Mẹo Debug

Đừng lãng phí 20 phút để soi một khối dữ liệu lồng nhau 5.000 ký tự. Khi một đối tượng JSON lớn gặp lỗi, tôi thường đưa nó qua một trình xác thực trước. Các công cụ như JSON Validator của ToolCraft sẽ đánh dấu chính xác dòng và ký tự bị thiếu dấu ngoặc hoặc đặt sai dấu phẩy. Nó hoạt động trên trình duyệt, vì vậy bạn có thể debug các đoạn mã production mà không cần gửi dữ liệu nhạy cảm đến máy chủ của bên thứ ba.

Kiểm tra cuối cùng

Thực hiện ba bước kiểm tra sau để xác nhận bản sửa lỗi của bạn đã ổn định:

  • Kiểm tra tính hợp lệ: SELECT COUNT(*) FROM table WHERE JSON_VALID(meta) = 0; (Kết quả phải là 0).
  • Kiểm tra kiểu dữ liệu: SELECT DISTINCT JSON_TYPE(meta) FROM table; (Phải trả về OBJECT hoặc ARRAY).
  • Kiểm tra trích xuất: SELECT meta->>"$.status" FROM table LIMIT 1;.

Một mẹo cuối cùng: hãy đảm bảo kết nối của bạn sử dụng utf8mb4. Nếu client của bạn gửi dữ liệu latin1 đến một cột JSON, trình phân tích cú pháp có thể hiểu sai các ký tự hợp lệ thành lỗi cú pháp.

Related Error Notes