github / github/copilot-cli

Deleting an evicted session silently no-ops: session reappears after restart, and ON DELETE CASCADE never fires

Đang mở
#4,754 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

area:sessions
Ngôn ngữ chính
Shell
Star
11.2k
Fork
1.9k
Merge trung bình
14 giờ 16 phút
Pull request đã merge (30 ngày)
6

Mô tả

Summary

Deleting a session that has been evicted from the app's in-memory session map appears to succeed in the UI, but nothing is written to data.db. The session reappears in the sidebar after restarting the app, and repeated delete attempts always fail the same way.

A second, related defect compounds it: the app does not enable SQLite foreign-key enforcement, so the schema's ON DELETE CASCADE rules never fire. Even successful deletes therefore leave orphaned workspaces and worktrees behind.

Environment

  • GitHub Copilot app 1.1.15 (commit b5f4206), Windows x86_64
  • Bundled Copilot CLI 1.0.83-5
  • Project type: multi-repo collection (2 member repos)
  • Sessions affected were nested/child sessions created from a parent session

Steps to reproduce

  1. Create a session (mine were child sessions spawned from a parent planning session).
  2. Leave it idle long enough for its CLI process to be reaped by idle_cli_reap_check. Mine were last used 3–4 days earlier.
  3. Right-click the session → Delete. The row disappears from the sidebar.
  4. Restart the app.
  5. The session is back.

Expected

The session is permanently deleted and does not return.

Actual

The delete handler emits only this, then returns:

INFO ws_handle_client_message{kind="delete_workspace"}: github_app::session::manager::lifecycle:
  session not found in memory during delete (already evicted) session_id=<id>

The two lines that indicate an actual delete never appear for these sessions:

INFO lifecycle: archived workspace workspace_id=<id>
INFO lifecycle: permanently deleted workspace workspace_id=<id>

The sidebar removes the row optimistically, so it looks like it worked until the next restart.

Evidence

Over 4 days I attempted to delete 3 child sessions 10 times. Every attempt produced only the "already evicted" line, and zero archive/delete lines were ever logged for their workspace IDs.

The contrast is visible within a single click-run. Sessions still resident in memory delete correctly:

09:01:59  lifecycle: archived workspace workspace_id=30b4e00c…
09:02:00  lifecycle: permanently deleted workspace workspace_id=30b4e00c…
09:02:09  lifecycle: archived workspace workspace_id=bb488886…
09:02:10  lifecycle: session not found in memory during delete (already evicted) session_id=271fa224…   <-- evicted, no-op
09:02:10  lifecycle: permanently deleted workspace workspace_id=bb488886…
09:02:13  lifecycle: session not found in memory during delete (already evicted) session_id=f6917bb6…   <-- evicted, no-op
09:02:15  lifecycle: session not found in memory during delete (already evicted) session_id=9d00e2a2…   <-- evicted, no-op
09:02:18  lifecycle: archived workspace workspace_id=0f208bbf…
09:02:19  lifecycle: permanently deleted workspace workspace_id=0f208bbf…

Four workspaces were deleted in that run and are genuinely gone. The three evicted sessions produced no DB writes at all and came back on the next launch.

Root cause (best guess)

The delete_workspace handler looks the live session up in the in-memory session map and returns early when it is absent, treating "not in memory" as "nothing to do". It should treat eviction as the normal case: skip the CLI/process teardown, then continue to the workspace archive and DB deletion.

Second defect: ON DELETE CASCADE never fires

PRAGMA foreign_keys is 0 (the SQLite default) on the app's connections to data.db. The schema declares ON DELETE CASCADE on 16 tables referencing workspaces(id) and 9 tables referencing sessions(id), but none of it takes effect.

Consequently, deleting a session leaves its workspaces row behind with session_id set to NULL, plus stale rows in workspace_checkout_bindings, workspace_parent_links, workspace_session_aliases and activity_items.

On my machine this had silently accumulated 11 orphaned workspaces, 5 of which still held 9 on-disk worktree checkouts (~16,500 files each) that no session referenced.

Impact

  • Sessions cannot be deleted once evicted. They return on every restart, with no error shown.
  • Disk usage grows unbounded. Orphaned worktrees are never reclaimed.
  • Orphaned bindings can make healthy sessions unopenable. The resume validator requires every workspace_checkout_bindings row's checkout_path to exist on disk. I separately hit this session's worktree is missing; recreate the worktree, then retry on a session whose only unsatisfied binding pointed at a repo that had been removed from the collection and no longer existed on disk. Recreate worktree cannot fix that — it only recreates checkouts for current collection members, silently leaves the stale binding unsatisfied, and additionally resets the session branch to the default branch. The session was permanently unopenable until I deleted the stale rows by hand.

Suggested fixes

  1. In the delete path, treat an evicted session as normal: skip CLI teardown, continue to archive + permanent delete.
  2. Set PRAGMA foreign_keys = ON on each connection so the existing cascade rules apply.
  3. Add a startup reconciliation that removes workspaces with no owning session and prunes their worktrees.
  4. Scope the resume validator to current collection members, or at minimum surface which binding failed so the error is actionable.

Workaround

Deleting the workspaces and sessions rows directly from data.db with PRAGMA foreign_keys=ON (so cascades fire), then removing the corresponding git worktrees and branches, cleans this up correctly.

Possibly related to #4709, also area:sessions and also involving collection worktree association.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu từ handler delete_workspace và các log vòng đời của trình quản lý phiên, sau đó kiểm tra schema của data.db và thiết lập kết nối để xác minh việc áp dụng khóa ngoại. Tái hiện sự cố với một phiên bị loại bỏ và xác minh rằng việc xóa vẫn được duy trì sau khi khởi động lại, các thao tác xóa theo tầng loại bỏ các hàng phụ thuộc, và các worktree được thu hồi; xem xét trình xác thực tiếp tục để tìm các liên kết cũ.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
git, sqlite
Lĩnh vực
backend, cli, database
Loại issue
Lỗi
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Sôi nổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
45/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.