Skip to content

fix: Opening the same project from several places at once no longer fails - #737

Merged
stefanhoelzl merged 1 commit into
mainfrom
investigate-startup-open-race
Oct 2, 2026
Merged

stefanhoelzl merged 1 commit into
mainfrom
investigate-startup-open-race

Conversation

@stefanhoelzl

Copy link
Copy Markdown
Owner
  • Symptom: ch ws create --project <path> issued while app:ready's startup project:open of the same project was in flight failed with Could not open project "<path>" (seen as a 1-in-10 flake of e2e/agent-turn.e2e.ts). The API server answers before app:ready runs, and a path never matches an open project by name, so any two concurrent opens of one path could collide — not only at startup, and independent of experimental.concurrent-hooks.
  • Root cause: the per-key idempotency rule for project:open blocked the duplicate; a blocked dispatch resolves to undefined, which workspace:open (and ch project open) read as failure.
  • idempotency-module: new per-key wait option — a duplicate is held until the reset event releases the key, which is handed straight to it (FIFO, one at a time). project:open uses it; every other rule still drops duplicates.
  • project:open: every exit now emits project:opened or project:open-failed. A cancelled prepare (declining git init) and a throwing prepare hook used to leave the key held, silently dropping every later open of that path.
  • ch progress: render project:open-failed from its reason field (it read a nonexistent error, so always printed "unknown error"); say nothing for already-open, report a cancel as a cancel.
  • Tests: wait-mode integration tests, prepare cancel/throw emit project:open-failed, progress rendering. Docs: docs/INTENTS.md, CLAUDE.md.

🤖 Generated with Claude Code

… failing

`ch ws create --project <path>` arriving while app:ready's startup open of
the same project was in flight failed with "Could not open project": the
per-key idempotency rule blocked the nested project:open, a blocked dispatch
resolves to undefined, and workspace:open reads that as failure. The API
server answers before app:ready runs, and a path never matches an open
project by name, so any two concurrent opens of one path could collide.

- idempotency-module: a per-key rule with `wait` holds a duplicate until the
  reset event releases the key, then hands the key straight to it (FIFO).
  project:open uses it; the other rules still drop duplicates.
- project:open: every exit now emits project:opened or project:open-failed.
  A cancelled prepare (declining git init) and a throwing prepare hook left
  the key held, silently dropping every later open of that path.
- ch progress: read project:open-failed's `reason` (it read a nonexistent
  `error`, so always printed "unknown error"); say nothing for already-open
  and report a cancel as one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@stefanhoelzl stefanhoelzl added the bug Something isn't working label Oct 2, 2026
@stefanhoelzl
stefanhoelzl enabled auto-merge (rebase) October 2, 2026 18:06
@stefanhoelzl
stefanhoelzl merged commit e9127ab into main Oct 2, 2026
17 checks passed
auto-merge was automatically disabled October 2, 2026 18:22

Pull Request is not mergeable

@stefanhoelzl
stefanhoelzl deleted the investigate-startup-open-race branch October 2, 2026 18:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant