fix: keep ACP sessions loadable when their working directory has been deleted
- 主要言語
- Rust
- スター
- 54.2k
- フォーク
- 6.2k
- 平均マージ
- 3日 2時間
- マージ済み PR(30日)
- 262
説明
## Problem
When a Claude Code (ACP) session's working directory no longer exists — e.g. the user deleted the git worktree the session was created in — the session becomes completely inaccessible in Goose Desktop. Loading it fails with **"Failed to Load Session / invalid directory path"** and offers only a "Go home" button. This blocks reading the session history *and* blocks reaching any control that could repoint the session at a valid directory, so the session is effectively lost with no recovery path.
Loading a historical session should be best-effort with respect to the environment: the stored transcript should still be readable even when the saved working directory is gone, and the user should be able to correct the path.
## Background
`loadSession` gates the entire load on the existence of the session's stored working directory, before any transcript is replayed.
1. The desktop UI loads a session by reading its stored `cwd` and passing it straight back to the server as the load `cwd`:
- `ui/desktop/src/acp/sessions.ts:199-207` — `loadAcpSession` fetches `initialSessionInfo.cwd` and calls `client.loadSession({ sessionId, cwd, mcpServers: [] })`.
2. The server rejects the load immediately if that directory is missing:
- `crates/goose/src/acp/server/load_session.rs:186` — `handle_load_session` calls `validate_absolute_cwd(&args.cwd)?` as its **first** step, before `replay_conversation_to_client` (line 205) ever runs.
- `crates/goose/src/acp/server.rs:878-880` — `validate_absolute_cwd` returns `invalid_params` with data `"invalid directory path"` when `!cwd.exists() || !cwd.is_dir()`. This is the exact string shown in the UI error.
3. Because the load fails there, the transcript is never replayed and the `session/update-working-dir` handler is unreachable:
- `crates/goose/src/acp/server/manage_sessions.rs` — `on_update_working_dir` exists and can repoint a loaded session, but it operates on a session that must already be loaded, which is impossible here.
This is the same class of hard-fail as #10113 ("Recipe-backed sessions should remain loadable when recipe metadata is incomplete or invalid"): `loadSession` aborts on a stale piece of session metadata and takes the whole transcript down with it. #10113 is scoped to recipe hydration; this issue is scoped to the working directory. A shared principle — historical session loads should be best-effort about environment/metadata — would address both.
## Reproduction
1. Create a Claude Code (ACP) session in Goose Desktop whose working directory is a git worktree.
2. Delete that worktree directory from disk.
3. Open the session in Goose Desktop.
4. Observe: "Failed to Load Session / invalid directory path", with only a "Go home" button. Session history is unreadable and there is no control to fix the path.
## Approach
Make historical session loading best-effort about the working directory instead of gating on it:
- In `handle_load_session` (`crates/goose/src/acp/server/load_session.rs`), do not hard-fail when the stored `cwd` is missing. The absolute-path check is still fine, but a non-existent directory should not abort the load. Replay the transcript regardless.
- Enforce directory existence only where it actually matters — when spawning the agent/extensions or when sending a new prompt/turn — not when merely reading history. Consider surfacing the missing-directory condition in the load response metadata so the UI can show a non-fatal warning.
- Ensure the existing `session/update-working-dir` control (`on_update_working_dir` in `crates/goose/src/acp/server/manage_sessions.rs`) is reachable for such a session, so the user can repoint it to a valid directory and resume. Surface an entry point for this in the desktop UI on the load-warning/error state.
- Note that `validate_absolute_cwd` (`crates/goose/src/acp/server.rs:871`) is shared by `new_session`, `fork_session`, `list_sessions`, and `manage_sessions`. Those paths *should* keep rejecting a missing directory (you can't start work in a directory that isn't there). Do not weaken the shared helper globally — relax only the historical-load path, or split the existence check out from the absolute-path check.
## Definition of done
- [ ] Opening an ACP session whose stored working directory has been deleted shows the full session history (read-only replay) instead of "invalid directory path".
- [ ] The user can correct/repoint the session's working directory from the UI for such a session and then resume it.
- [ ] `new_session` / `fork_session` still reject a non-existent `cwd` (starting new work in a missing directory remains an error).
- [ ] A test covers loading a session whose working directory no longer exists (transcript loads; new-turn path still validates the directory).
## Out of scope
- The broader recipe-metadata reload work tracked in #10113 (related, but distinct fix).
- Auto-recreating or garbage-collecting deleted worktrees.
- General session-list load failures unrelated to a missing working directory (e.g. #10480).
コントリビューションガイド
評価
この issue はまだ評価されていません。