Skip to content

fix(app): separate location identity from sync failures - #46695

Merged
Hona merged 2 commits into
anomalyco:v2from
Hona:location-sync-recovery
Sep 2, 2026
Merged

Hona merged 2 commits into
anomalyco:v2from
Hona:location-sync-recovery

Conversation

@Hona

@Hona Hona commented Sep 2, 2026 •

Copy link
Copy Markdown
Member
  • Keep the composer and draft visible while workspace data loads or a sync read fails. Remove the separate error flag that misclassified read failures as missing directories.
  • Retry current-location reads up to three times, stop stale retries after navigation/disconnection, and refresh active-session metadata on reconnect.
  • Seed newly created worktrees through data.location.syncInfo() before opening the session, matching the TUI fix in fix(tui): seed moved worktree location #44143. Manual workspace movement remains available.

App-only: no server, protocol, shared-client, CLI, or TUI changes.

flowchart LR
  Select[Select location] --> View[Keep composer and cached data]
  Select --> Sync[Sync current location]
  Sync -->|Success| Cache[Update shared data]
  Cache --> View
  Sync -->|Failure| Retry[Bounded read retries]
  Retry -->|Exhausted| Keep[Preserve composer and draft]
Loading

Valid worktree with a failing agent-list request:

Before After

Cold session entry from Home, three serial production-build samples per revision:

Metric Before (v2) After
First correct content, median 815 ms 466 ms
First correct content, maximum 870 ms 535 ms
Stable content, median 838 ms 495 ms

Small local sample; not a performance guarantee.

@Hona
Hona requested a review from Brendonovich as a code owner September 2, 2026 00:16
Copilot AI lite review requested due to automatic review settings September 2, 2026 00:16

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

New client tests construct session.moved events without the required projectID, which is inconsistent with the generated types/schema and can break typechecking or misrepresent real event payloads.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR refines location/session recovery so transient connection or workspace-sync failures don’t trigger “missing directory” recovery flows, while still following real location moves and only offering directory recovery after a confirmed LocationNotFoundError (with a placement recheck).

Changes:

  • Introduces LocationNotFoundError in the protocol/OpenAPI and updates the generated client to surface the 404 response for GET /api/location.
  • Updates the server location.get handler to confirm missing/non-directory local paths before booting location services (and to avoid classifying non-missing filesystem/config/IO failures as “missing”).
  • Updates client session/location data resolution to preserve live session.moved updates across concurrent reads and to refresh session placement on reconnect, with added unit and E2E regression coverage.
File summaries
File Description
packages/server/test/location.test.ts Adds server-level tests covering local path confirmation, non-missing failure handling, and workspace placement behavior.
packages/server/src/routes.ts Registers FSUtil node so the location handler can stat local paths.
packages/server/src/handlers/location.ts Adds local filesystem confirmation + LocationNotFoundError handling for location.get, scoped by workspace placement.
packages/protocol/test/location.test.ts Verifies LocationNotFoundError encoding and OpenAPI declaration scoping to location.get.
packages/protocol/src/groups/location.ts Declares LocationNotFoundError as an endpoint error for location.get.
packages/protocol/src/errors.ts Introduces LocationNotFoundError with optional workspaceID and HTTP 404 status.
packages/protocol/src/api.ts Adjusts API composition so LocationGroup is added without location middleware.
packages/protocol/openapi.json Updates OpenAPI to include the new 404 response and schema.
packages/client/test/solid-data.test.ts Adds tests for preserving session.moved effects across concurrent reads (contains contract issues noted in comments).
packages/client/src/solid/data.ts Tracks in-flight session reads to preserve move events until the next authoritative read.
packages/client/src/promise/generated/types.ts Adds generated LocationNotFoundError type guard/type.
packages/client/src/promise/generated/client.ts Adds 404 to declared statuses for location.get.
packages/app/test-browser/session-resolution.test.ts Adds browser test ensuring reconnect refresh keeps cached content visible.
packages/app/src/workspaces/location.tsx Adds retry-in-place behavior and placement refresh before offering directory recovery UI.
packages/app/src/session/session-resolution.ts Gates resolution work on connection state to preserve cached content across disconnect/reconnect.
packages/app/src/session/route.tsx Wires connected + workspace/session info into LocationProvider for recovery decisions.
packages/app/src/runtime/server/errors.ts Adds isLocationNotFoundError classifier for precise missing-location handling.
packages/app/src/runtime/server/errors.test.ts Adds unit coverage for isLocationNotFoundError classification boundaries.
packages/app/e2e/regression/session-location-sync.spec.ts Adds E2E regressions for sync failures and moved-session refresh flows.
packages/app/e2e/regression/session-location-missing.spec.ts Updates E2E missing-location coverage to use the new 404 error contract and refresh behavior.
Review details

Suppressed comments (1)

packages/client/test/solid-data.test.ts:268

  • session.moved events require projectID on every move, but this fixture only includes it for seq === 1. That makes the test data inconsistent with the event schema/types and can hide regressions (or fail typechecking if tests are included in typecheck).
            data: {
              sessionID: info.id,
              location: { directory: `/moved/${info.id}/${seq}` },
              ...(seq === 1 ? { projectID: `project_${info.id}`, subpath: "intermediate" } : {}),
            },
  • Files reviewed: 18/20 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/client/test/solid-data.test.ts Outdated
created: 1,
type: "session.moved",
durable: { aggregateID: stale.id, seq: 1, version: 1 },
data: { sessionID: stale.id, location: { directory: "/moved" } },
@Hona Hona changed the title fix(app): keep sync failures out of location recovery fix(app): separate location identity from sync failures Sep 2, 2026
@Hona
Hona merged commit 48927df into anomalyco:v2 Sep 2, 2026
10 checks passed
jinhuang712 pushed a commit to jinhuang712/opencode that referenced this pull request Sep 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants