[triage:ui-05-app-deeplink-fixed-sleep-race] Cold-start deep-link dispatch relies on a fixed 1500ms sleep (race)
- Dominant language
- Rust
- Stars
- 72
- Forks
- 13
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 5
Description
Imported from Capsem triage report `ui-05-app-deeplink-fixed-sleep-race.md`.
- Severity: `low`
- Category: `bug`
- Area: `capsem-app`
- Location: `crates/capsem-app/src/main.rs:278-289`
- Confidence: `verified`
## Summary
On cold start with `--connect `, the app waits a hard-coded 1500ms, then
evals `if (window.__capsemDeepLink) { window.__capsemDeepLink({...}) }`. If the
frontend has not yet mounted `__capsemDeepLink` after 1500ms (slow machine,
heavy first paint, debug build), the guard is false and the deep link is
silently dropped with no retry. There is no readiness handshake — the timeout is
a guess.
## Evidence
```
// crates/capsem-app/src/main.rs:284
tauri::async_runtime::spawn(async move {
tokio::time::sleep(std::time::Duration::from_millis(1500)).await;
dispatch_deep_link(&window, &id, action.as_deref()); // fire once
});
```
`dispatch_deep_link` -> `window.eval(build_deep_link_script(...))`, and the
script is `if (window.__capsemDeepLink) { ... }` (`main.rs:104-111`) — a missing
hook is a no-op, not a retry.
Mitigation that exists: for the cold-start case the frontend also reads
`connect`/`action` from the URL query string in `onMount`
(`frontend/src/lib/components/shell/App.svelte:53-69`), so the initial launch
usually still opens the VM tab even if the eval fires too early. The eval path
is the *only* mechanism for the already-running (single-instance) case
(`main.rs:266-277`), but there the window is already mounted and dispatch is
immediate, so the 1500ms sleep does not apply.
## Impact
Low: the cold-start eval can lose the deep link, but the URL-param path normally
covers that exact case, so user-visible breakage is unlikely. The fixed timeout
is nonetheless fragile and the eval path has no retry/handshake.
## Suggested fix
Replace the fixed sleep with a readiness signal: have the frontend invoke a
`deep_link_ready` IPC command (or emit an event) once `__capsemDeepLink` is
installed, and dispatch from the Rust side on that signal. Failing that, retry
the eval a few times with backoff and stop once the hook responds.
## Triage
Confirmed from the local reviewed report in `/Users/elie/git/capsem/tmp/bugs/ui-05-app-deeplink-fixed-sleep-race.md`. Track implementation in the triage sprint; add regression coverage before fixing.
Contributor guide
Research direction
Start in crates/capsem-app/src/main.rs:104-111 and 278-289, then inspect frontend/src/lib/components/shell/App.svelte:53-69 to understand hook installation and URL fallback. Add regression coverage before replacing the fixed delay with a readiness signal or bounded retry, and verify cold-start deep links are dispatched after the frontend hook is available.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- desktop, frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100