Skip to content

fix(cli): recover from concurrent service replacement during startup #35801

Description

@kitlangton

Summary

A TUI starting during managed-daemon replacement should survive the handoff. If its initial transport disappears, startup should rediscover the winning registration and retry instead of exiting with a raw transport error.

Current state

The original incident produced seven live service candidates because concurrent starts raced through registration. V2 now elects one service process with a channel-scoped file lock (dd842f9; related PR #35826), so the many-candidate race described in the original report is no longer the current architecture.

The remaining client-side requirement is still valid: a startup transport can disappear during intentional daemon replacement. Event-stream reconnect already rediscovers the managed service, but initial TUI hydration/API requests can fail before that recovery path owns startup.

Expected behavior

  • Fresh startup may replace a healthy version-mismatched daemon according to service policy.
  • Concurrent service candidates elect one owner.
  • A TUI whose startup transport disappears rediscovers the current registration and retries bounded initial hydration.
  • The user does not need to launch OpenCode a second time.
  • Explicit --server failures remain loud; only managed-service startup uses rediscovery.

Acceptance criteria

  • Reproduce a daemon handoff between transport discovery and initial TUI hydration.
  • The first TUI invocation rediscoveries the winning managed daemon and completes startup.
  • Retry is bounded and does not create restart authority beyond ordinary Service.start policy.
  • Multiple concurrent clients converge on the elected daemon.
  • Tests cover transport loss before the event stream connects and during initial hydration.

Original observation

Observed on macOS while upgrading 0.0.0-next-15078 to 0.0.0-next-15081: the first TUI exited with a transport error and a second invocation succeeded after registration stabilized.

Discussion: https://slack.com/archives/C0BE69AHCQP/p1783527674019519

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

2.0bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions