Incident report: Vercel environment variables cleared during synchronization
Bài tóm tắt Trigger.dev 2026 3. Quy mô lớn Độ khó: Trung bình
Trigger.dev · 2026 · 3. Quy mô lớn · Độ khó: Trung bình — bài gốc
Bối cảnh
- Trigger.dev đồng bộ biến môi trường từ Vercel trước mỗi lần build. API của Vercel trả biến loại Sensitive với
value: ""vì integration không được đọc giá trị. - Đường sync before-build đã bỏ qua kiểu secret cũ của Vercel nhưng sót kiểu Sensitive. Bug này nằm im vì endpoint import của Trigger.dev vứt mọi giá trị rỗng.
Chuyện gì xảy ra
- 6/10/2026, 12:21 UTC: bật toàn cục tính năng cho phép lưu chuỗi rỗng (một số ứng dụng cần biến có mặt nhưng trống). Hành vi vứt giá trị rỗng biến mất, nên bug sync lộ ra: giá trị thật bị ghi đè bằng chuỗi rỗng.
- Đã thử trên một organization test, nhưng dữ liệu test không có biến Sensitive nên test vẫn qua.
- Đường setup integration và manual pull xử lý Sensitive đúng; đường before-build là một bản cài đặt riêng, xử lý khác.
- 121 organization bị ảnh hưởng (production, staging, preview). Dashboard vẫn hiện tên biến nên người dùng thấy lỗi thiếu credential mà biến "vẫn nằm đó". Ai nhập lại giá trị thì build sau lại xoá tiếp.
- 12:53 workflow nội bộ hỏng → 15:02 tìm ra nguyên nhân → 15:10 tắt tính năng (2 giờ 49 phút).
Khôi phục
- Không lấy lại được từ Vercel vì API không trả giá trị Sensitive. Phải dựng lại bản sao database ngay trước sự cố và chép dữ liệu đã mã hoá sang, không giải mã secret của khách.
- Mỗi giá trị chỉ được khôi phục nếu vẫn rỗng và không có lần ghi nào khác ngoài lần ghi của sự cố, kiểm tra nguyên tử cùng lúc ghi, để không đè lên credential khách đã xoay vòng. Xong lúc 19:52 UTC.
Khắc phục (theo Trigger.dev)
- Bỏ qua biến Sensitive trong sync; thêm bảo vệ phía nhận để integration không lặng lẽ thay giá trị có sẵn bằng giá trị rỗng.
- Test theo toàn bộ đường đi từ response của Vercel tới giá trị lưu, gồm cả biến Sensitive, mã hoá, cố ý rỗng; gộp quy tắc của các đường sync tách rời.
- Viết quy trình khôi phục; cân nhắc lưu lịch sử giá trị đã mã hoá để khôi phục không cần dựng lại database.
- Email khách nhanh hơn (lần đầu gửi sau khoảng một giờ).
Bài học cho SWE
- Sửa một hành vi có thể gỡ lớp che cho bug khác. Hành vi "vứt giá trị rỗng" là một lớp bảo vệ không ai ghi lại (Deploy và release an toàn).
- Test trên tổ chức thử chỉ có giá trị khi dữ liệu thử phủ các trường hợp biên của dữ liệu thật.
- Hai đường code làm cùng một việc sẽ lệch nhau theo thời gian.
- Ghi đè không có lịch sử thì khôi phục rất đắt. Khi khôi phục hàng loạt, phải kiểm tra điều kiện để không đè lên thao tác người dùng đã làm sau sự cố (Sự cố và postmortem).
- Khôi phục giá trị không replay các run đã lỗi; replay cần xem tác dụng phụ (idempotency).
Liên quan
- Trigger.dev 2026 (sự cố khác cùng năm)
- Sự cố và postmortem · Deploy và release an toàn
Được nhắc tới trong
Chủ đề (2)
Công ty (1)
Bài tóm tắt (1)