google / google/capsem

[triage:ui-05-app-deeplink-fixed-sleep-race] Cold-start deep-link dispatch relies on a fixed 1500ms sleep (race)

Open
#155 0 comments 0 reactions 0 assignees View on GitHub
component:app type:bug
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.