Skip to content

fix(tui): only offer a new directory when the location is missing - #57532

Closed
ggrabarz wants to merge 1 commit into
anomalyco:devfrom
ggrabarz:tui-location-sync
Closed

ggrabarz wants to merge 1 commit into
anomalyco:devfrom
ggrabarz:tui-location-sync

Conversation

@ggrabarz

Copy link
Copy Markdown

Issue for this PR

Closes #55250

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

The TUI replaced the composer with the blocking "Session location unavailable — Choose another directory to continue this session." prompt after any failed location sync, even when the folder was still there.

LocationProvider.sync (packages/tui/src/context/location.tsx) set the location error on every sync rejection. The sync fans out to a dozen catalog endpoints under one Promise.all (packages/client/src/solid/data.ts, location.sync), so one transient failure fails the whole sync. Under load the server answers GET /api/model with 503 ServiceUnavailableError: Location plugins did not finish activating (the 5s awaitPlugins budget in packages/server/src/location.ts), the sync rejects, and the TUI claims the directory is gone and offers to move the session somewhere else.

Only the server's typed LocationNotFoundError proves the folder is missing. The web client already gates on it (packages/app/src/workspaces/location.tsx); the TUI did not.

This change:

  • splits the location state into missing (the server's LocationNotFoundError) and error (anything else), so only a genuinely missing directory mounts the recovery prompt;
  • retries a failed sync with backoff, so a transient failure heals on its own instead of leaving the session without its catalog;
  • compares the missing directory with sameDirectory, so a Windows path that differs only in case still matches;
  • drops a duplicated location read that made every failed sync ask the server twice.

A transient failure stays visible as location.error instead of being swallowed.

How did you verify your code works?

  • packages/tui/test/session-location-unavailable.test.tsx drives the real app: a transient /api/model 503 is retried and the composer stays usable, a persistent 503 keeps the composer usable, and a LocationNotFoundError still shows the recovery prompt. Reverting the source change fails the first two and reproduces the reported screen verbatim.
  • packages/tui/test/cli/tui/location-provider.test.tsx: a missing location is asked exactly once (retrying cannot succeed until the folder changes), while any other failure is retried and lands in error, never in missing.
  • cd packages/tui && bun test --timeout 60000 test/session-location-unavailable.test.tsx test/cli/tui/location-provider.test.tsx test/cli/tui/prompt-move.test.tsx test/cli/tui/data.test.tsx test/context/session-tabs.test.tsx test/component/session-tabs-status.test.tsx test/session-dialog-resync.test.tsx -> 103 pass / 0 fail. With the source change reverted: 99 pass / 4 fail (the four new cases; no other test changes state).
  • bun run typecheck and oxlint are clean.

Screenshots / recordings

No visual change for a genuinely missing folder. The recovery prompt no longer appears for a folder that is present.

Related

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

The TUI mounted the blocking "Session location unavailable" recovery prompt
after any failed location sync, even when the folder was still there. The
sync fans out to a dozen catalog endpoints under one Promise.all, so a single
transient failure failed the whole sync and the TUI offered to move the
session to another directory.

Only the server's typed LocationNotFoundError proves the folder is gone, so
the location state now separates `missing` from `error`, and a failed sync is
retried before it is reported. The missing directory is compared with
sameDirectory, and the duplicated location read is dropped.
@github-actions

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

@opencode-agent opencode-agent Bot closed this Oct 20, 2026
@opencode-agent

Copy link
Copy Markdown
Contributor

Thanks for the thorough write-up and the end-to-end tests, @ggrabarz!

I think this duplicates #55940, which is still open and makes the same core change: LocationProvider.sync flags the location as unavailable only on the server's LocationNotFoundError.

Your additions are worth raising there: retrying with backoff, keeping other failures visible as location.error instead of dropping them, the sameDirectory comparison, and removing the extra syncInfo read. It would help to suggest them on #55940 in a review or comment, or to share your regression tests there.

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.

tui: false "Session location unavailable" prompt after network reconnect

1 participant