3 điểm bởi GN⁺ 22 ngày trước | 1 bình luận | Chia sẻ qua WhatsApp
  • Đã có báo cáo về hiện tượng các thay đổi của dự án bị tự động xóa sau mỗi 10 phút trong môi trường macOS
  • Kết quả điều tra cho thấy nguyên nhân không phải do Claude Code mà là một công cụ tự động hóa cục bộ riêng do người dùng tạo ra, đã định kỳ chạy git reset --hard origin/main thông qua GitPython
  • Do dùng chung thư mục làm việc, Claude Code trông như là nguyên nhân, nhưng thực tế việc reset được thực hiện bởi một script bên ngoài
  • Nhóm Claude Code đã nói rõ rằng trong mã nội bộ không có logic thực thi lệnh này, đồng thời giải thích rằng hành vi tương tự chỉ có thể xảy ra khi dùng tùy chọn --dangerously-skip-permissions
  • Cuối cùng, vấn đề được kết luận là sự cố từ công cụ của người dùng chứ không phải lỗi của Claude Code, và tiêu đề đã được sửa lại trước khi đóng

Hiện tượng và môi trường

  • Quan sát thấy Claude Code thực hiện git fetch origingit reset --hard origin/main trong kho lưu trữ dự án của người dùng theo chu kỳ 10 phút
  • Hành vi này xóa toàn bộ thay đổi của các tệp đã được theo dõi nhưng chưa commit, trong khi các tệp chưa được theo dõi vẫn được giữ nguyên
  • Trong môi trường Git worktree, hiện tượng reset như vậy không xảy ra
  • Thông tin môi trường
    • Phiên bản Claude Code: 2.1.87 (Homebrew cask, Bun binary)
    • OS: macOS 15.4 (Darwin 25.3.0, arm64)
    • Shell: zsh

Quá trình điều tra

  • Trong Git reflog, log reset: moving to origin/main đã được ghi lại hơn 95 lần với chu kỳ 10 phút
    • Độ lệch giữa các phiên là khác nhau, nhưng trong từng phiên thì lặp lại chính xác mỗi 600 giây
  • Trong thử nghiệm tái hiện theo thời gian thực, tệp được theo dõi (api.ts) được khôi phục về trạng thái ban đầu tại thời điểm reset, còn tệp không được theo dõi (.canary-test.txt) vẫn giữ nguyên
  • Kết quả giám sát thư mục .git/ bằng fswatch cho thấy mô hình các tệp .git/refs.git/logs/HEAD bị sửa đổi đúng vào thời điểm reset
  • Theo lsof, tiến trình duy nhất dùng CWD của kho lưu trữ đó là Claude Code CLI
  • Không phát hiện tiến trình git bên ngoài, nên suy đoán rằng thao tác được thực hiện nội bộ bằng libgit2 hoặc tương tự
  • Trong môi trường worktree, hoàn toàn không có bản ghi reset nào trong reflog

Các nguyên nhân đã bị loại trừ

  • Git hooks, hook người dùng của Claude Code, cập nhật plugin, đồng bộ đám mây của macOS, Cron/LaunchAgents, IDE, Time Machine, công cụ theo dõi tệp... đều được xác nhận là không liên quan
  • Từng mục đã được loại trừ bằng cách kiểm tra trực tiếp cấu hình và tiến trình thực tế

Phân tích binary (một phần)

  • Một phần hàm trong binary Claude Code có chứa đoạn mã thực hiện lệnh ["fetch","origin"]
  • Có tồn tại hàm bao cho git pull và logic quản lý trạng thái fileHistory, nhưng không xác định được bộ hẹn giờ chu kỳ 10 phút

Ảnh hưởng

  • Các thay đổi chưa commit bị tự động xóa sau mỗi 10 phút, khiến trong một phiên làm việc 2 giờ đã có hơn ba lần chỉnh sửa bị mất
  • Khi mọi thay đổi đều đã commit thì việc reset không còn ý nghĩa, nên vấn đề có đặc tính xuất hiện gián đoạn

Phản hồi từ nhóm Claude Code

  • Jarred-Sumner nói rõ: “Trong bản thân Claude Code không có mã chạy git reset --hard origin/main
  • Ông giải thích rằng nếu dùng tùy chọn --dangerously-skip-permissions, Claude có thể chạy lệnh shell mà không cần prompt, và nếu lệnh /loop 10m <prompt> định kỳ yêu cầu “đồng bộ với remote” thì git fetch && git reset --hard origin/main có thể được thực thi
  • Cách kiểm tra được đề xuất gồm
    1. grep -r "reset --hard" ~/.claude/projects/ để tìm trong log phiên
    2. Chạy claude --debug-file /tmp/debug.txt --dangerously-skip-permissions, chờ 10 phút, rồi tìm bằng grep -i bash /tmp/debug.txt | grep reset
  • Tính năng fileHistory của Claude Code không liên quan đến git và không gọi git reset ở bên trong

Kết luận cuối cùng

  • Trong bản cập nhật ngày 30 tháng 3 năm 2026, nguyên nhân gốc rễ của vấn đề được xác định là công cụ cục bộ riêng của người dùng chứ không phải Claude Code
  • Công cụ đó dùng GitPython để thực hiện hard reset mỗi 10 phút và đang theo dõi cùng thư mục với Claude Code
  • Issue được đóng với trạng thái “not planned”, và tiêu đề được sửa từ “Claude Code chạy reset” thành “Công cụ tự động hóa của tôi chạy reset”

Cách khắc phục tạm thời

  • Khi dùng git worktree thì không bị ảnh hưởng bởi việc reset
  • Có thể bảo vệ thay đổi bằng cách commit thường xuyên

Các issue liên quan

  • #8072 — Vấn đề chỉnh sửa mã liên tục bị hoàn tác
  • #7232 — Mất dữ liệu do chạy git reset --hard mà không có phê duyệt
  • #32793 — Lệnh claude install thay đổi sai URL git remote (trường hợp tương tự nhưng là vấn đề riêng)

1 bình luận

 
Ý kiến trên Hacker News
  • Đây là cập nhật do chính tác giả đăng
    Theo liên kết issue, nguyên nhân gốc rễ của vấn đề không phải là Claude Code mà là lỗi trong một công cụ do chính tác giả tạo ra để test cục bộ
    Công cụ đó đã thực hiện hard reset ở mỗi chu kỳ để đồng bộ thư mục làm việc cục bộ với remote, qua đó xóa sạch mọi thay đổi chưa được commit

    • Buồn cười là tác giả nói đã làm rất nhiều “điều tra” mà lại không nghĩ tới chuyện tắt Claude trong 10 phút
      Nếu đổi tiêu đề thành kiểu “Lập trình viên viết script reset git repo mỗi 10 phút rồi quên mất, sau đó đổ lỗi cho Claude Code” thì tôi sẽ bỏ cờ đánh dấu
  • Vấn đề thật sự là dấu gạch nối kép trong tiêu đề đã bị HN tự động đổi thành en dash

    • Trong LaTeX, dấu gạch nối kép được dùng như en dash, còn gạch nối ba là em dash
    • Bản thân tôi vốn cũng nghĩ nên giữ nguyên gạch nối kép, nhưng xét theo truyền thống của LaTeX và Typst thì en dash lại phù hợp hơn
    • Mẹo chuyên gia: sao chép nguyên tiêu đề HN rồi dán vào dòng lệnh là rất nguy hiểm
    • Ban đầu nó phải được viết bằng hai dấu gạch nối như “--hard”
    • Có quy ước rằng hai dấu là en dash, ba dấu là em dash
  • Tôi cũng đã tự điều tra vấn đề này, và bản thân Claude Code không có đoạn mã nào chạy git reset --hard origin/main
    Rất có thể lập trình viên đã chạy lệnh như /loop 10m, hoặc tạo một tác vụ cron để reset git mỗi 10 phút

    • Có lẽ họ đã nhầm đó là một tính năng vô hại kiểu “đồng bộ định kỳ với server”
  • Khó mà tin được chuyện giám sát tiến trình mỗi 0,1 giây mà vẫn không thấy tiến trình git nào
    Lệnh git chạy quá nhanh nên với khoảng thời gian đó sẽ không bắt được
    Thay vào đó, cách tốt hơn là bọc git trong $PATH để ghi log mọi lần thực thi

    • Cái này giống như Claude Code đang tự đuổi theo cái đuôi của chính nó. Không debug được nên có vẻ như nó đang tự định tạo bug report
      Thậm chí có thể nó đã gửi một cách “agentic” mà không cần người dùng nhập gì cả (chỉ là suy đoán thôi)
      Liên kết issue
    • Trong trường hợp này, eBPF rất hữu ích. Ví dụ, dùng script execsnoop của bpftrace thì có thể theo dõi mọi tiến trình được thực thi trên hệ thống
  • Bài này có thể khiến người ta hiểu lầm rằng một vấn đề của cá nhân là vấn đề của cả hệ thống
    Có vẻ như đã có một phần hỏng ngữ cảnh nào đó

    • Tôi cũng đã gặp chuyện tương tự vài lần. Có lần thậm chí còn bị force push lên GitHub
      Claude từng làm hỏng theo chuỗi stash → thay thế bằng sed → xung đột → reset --hard
      Vì vậy tôi viết cảnh báo sau ở đầu CLAUDE.md
      “Cấm thay thế hàng loạt bằng sed, tuyệt đối không được dùng các lệnh git mang tính phá hủy như git push --force, git reset --hard
      Từ sau đó mọi thứ khá hơn nhiều
    • Có thể bạn đúng. Nhưng chỉ cần ngữ cảnh hỏng 0,1% thì trong 1000 tác vụ sẽ có một tác vụ làm mất dữ liệu
    • Thật ra kiểu vấn đề này có thể chặn hoàn toàn bằng phòng vệ kỹ thuật.
      Nếu gắn hook để chặn một số lệnh git nhất định thì hệ thống vẫn an toàn bất kể độ bất định trong dự đoán của mô hình
      Nhìn chuyện này lại thấy nhiều người đã quên nguyên tắc nền tảng của kỹ thuật ngày xưa — quy trình có tính quyết định và lặp lại được
    • Cuối cùng thì LLM thỉnh thoảng vẫn làm những chuyện thật sự ngu ngốc. Chỉ vậy thôi
  • Tôi cũng gặp vấn đề tương tự
    Bình thường tôi chạy claude-code trong sandbox (bwrap, srt), nhưng nếu chạy bên ngoài thì cứ mỗi lần xóa /command hoặc đóng menu là nó lại gọi gh
    Tôi dùng KeepassXC làm trình quản lý bí mật nên hộp thoại xin phê duyệt bật lên mỗi lần, thành ra nhận ra ngay
    Khi hỏi Claude thì nó nói nguyên nhân là do tính năng git context.
    Vì KeepassXC không cho phép cấp quyền theo phiên, nên cuối cùng lần nào cũng phải xác thực lại

  • Nếu có thiết lập quyền thì đáng lẽ chuyện này phải bị ngăn chứ
    Nhưng vì người dùng chạy với tùy chọn --dangerously-skip-permissions, nên phải chấp nhận hành vi khó lường

    • Dù vậy, dùng pretooluse hook thì vẫn có thể ngăn được ngay cả khi bật tùy chọn đó
    • Đọc tài liệu permissions của Anthropic thì không rõ quyền thực sự được cưỡng chế như thế nào.
      Cũng có thể hiểu là có thể bị vượt qua bằng prompt injection
    • Chạy trên repo thật mà không có quyền kiểm soát là tự chuốc lấy sự cố xóa dữ liệu
      Một quy tắc mà không chặn nổi hard reset thì chỉ là để trưng bày
    • Các quy tắc và quyền hiện tại không phải cờ chương trình, mà chỉ là văn bản mà agent “tin rằng mình phải tuân theo”
  • Chính tác giả đã xác nhận nguyên nhân không phải Claude Code mà là lỗi trong công cụ test cục bộ do anh ta tự làm

    • Tức là đây là một báo cáo sai
      Liên kết issue
    • Cách nói “công cụ tôi tự làm” hơi mơ hồ. Rất có thể đó là một công cụ vibe-coded dựng vội
    • Thật ra bản thân ticket này cũng có thể đã được tạo ra từ kết quả phân tích của Claude Code (tức là hallucination)
  • Không có gì lạ khi dùng công cụ phát triển blob nhị phân kiểu SaaS lại sinh ra những lỗi khó debug như thế này

  • Cuối cùng chính người dùng đã tìm ra nguyên nhân, và công cụ của họ mới là thứ gây ra vấn đề
    Chuyện kiểu này trước đây đã từng có, bây giờ vẫn có.
    Bản thân tôi cũng từng tự tay phá nát mọi thứ đủ nhiều lần mà không cần LLM trợ giúp
    Vì thế tôi luôn làm việc với Time Machine của Mac.
    Cả khi Claude xóa file, chỉ cần hiện “khôi phục chứ?” là có cảm giác như Claude cũng thở phào nhẹ nhõm
    Backup thực sự là sợi dây cứu mạng