can1357/oh-my-pi · error · RpcError

RPC client is already started

Error message

RPC client is already started

What it means

start() spawns the agent subprocess and initializes transport state; it refuses to run twice on the same RpcClient instance. If self._process is already set (client previously started and not stopped), this RpcError is raised.

Source

Thrown at python/omp-rpc/src/omp_rpc/client.py:577

            return "".join(self._stderr_chunks.snapshot())

    @property
    def command(self) -> tuple[str, ...]:
        return self._build_command()

    @property
    def protocol_errors(self) -> tuple[RpcProtocolError, ...]:
        with self._state_lock:
            return self._protocol_errors.snapshot()

    @property
    def listener_errors(self) -> tuple[ListenerErrorEvent, ...]:
        with self._state_lock:
            return self._listener_errors.snapshot()

    def start(self) -> RpcClient:
        if self._process is not None:
            raise RpcError("RPC client is already started")

        self._ready.clear()
        self._stopping = False
        self._closed_error = None
        self._ready_received = False
        self._ready_event = None
        self._protocol_version = 1
        self._protocol_v2_enabled = False
        self._frame_decoder = _RpcFrameDecoder()
        self._events.clear()
        self._async_errors.clear()
        self._scheduled_agent_runs = 0
        self._completed_agent_runs = 0
        self._last_schedule_async_error_index = 0
        self._ui_requests = queue.Queue()
        with self._state_lock:
            self._stderr_chunks.clear()
        with self._state_lock:

View on GitHub (pinned to 9690622007)

Solutions

  1. Guard calls: only call start() if the client is not already running (track your own started flag or check process state if exposed).
  2. Wrap start() in try/except RpcError and treat 'already started' as success for idempotent initialization.
  3. For restarts, call stop() before start().
  4. Ensure only one code path owns the client lifecycle (centralize start/stop).

Example fix

# before
client.start()  # may run twice

# after
try:
    client.start()
except RpcError as exc:
    if "already started" not in str(exc):
        raise  # already running: safe to continue
Defensive patterns

Strategy: try-catch

Try / catch

try:
    client.start()
except RpcError as exc:
    if "already started" not in str(exc):
        raise  # idempotent start: safe to continue

Prevention

When it happens

Trigger: Calling client.start() twice without an intervening stop(), e.g. retry logic re-invoking start after startup, or shared initialization code running start on an already-started client.

Common situations: Idempotency guards missing around init; restart logic calling start() instead of stop()-then-start(); multiple modules each calling start() on a shared singleton client.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/38f663ba9f4749e5. Report an issue: GitHub.