libnyanpasu/clash-nyanpasu · error

IPC server is already initialized

Error message

IPC server is already initialized

What it means

Ipc::connect() bails with 'IPC server is already initialized' when self.oneshot_server is None. Note the inverted-looking guard: once the server slot has been consumed (already connected/accepted), connect refuses to run again, enforcing a single connection per Ipc instance.

Source

Thrown at backend/nyanpasu-egui/src/ipc.rs:33

pub enum Message {
    Stop,
    UpdateStatistic(StatisticMessage),
    UpdateLogo(LogoPreset),
}

pub struct IPCServer {
    oneshot_server: Option<ipc::IpcOneShotServer<IpcSender<Message>>>,
    tx: Option<IpcSender<Message>>,
}

impl IPCServer {
    pub fn is_connected(&self) -> bool {
        self.tx.is_some()
    }

    pub fn connect(&mut self) -> anyhow::Result<()> {
        if self.oneshot_server.is_none() {
            anyhow::bail!("IPC server is already initialized");
        }

        let (_, tx) = self.oneshot_server.take().unwrap().accept()?;
        self.tx = Some(tx);
        Ok(())
    }

    pub fn into_tx(self) -> Option<IpcSender<Message>> {
        self.tx
    }
}

pub fn create_ipc_server() -> anyhow::Result<(IPCServer, String)> {
    let (oneshot_server, oneshot_server_name) = ipc::IpcOneShotServer::new()?;
    Ok((
        IPCServer {
            oneshot_server: Some(oneshot_server),
            tx: None,

View on GitHub (pinned to f7dbce2997)

Solutions

  1. Check is_connected() before calling connect() and skip if already connected
  2. Create a fresh Ipc instance instead of reconnecting the old one
  3. Reuse the existing tx channel rather than re-accepting

Example fix

// before
ipc.connect()?;
// after
if !ipc.is_connected() {
    ipc.connect()?;
}
Defensive patterns

Strategy: type-guard

Validate before calling

if ipc.is_connected() {
  return Ok(()); // already connected
}

Type guard

pub fn is_connected(&self) -> bool {
  self.tx.is_some()
}

Try / catch

match ipc.connect() {
  Ok(()) => {},
  Err(e) if e.to_string().contains("already initialized") => {}, // idempotent no-op
  Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling connect() a second time on the same Ipc instance after the oneshot server was already taken, or on an instance constructed without a server.

Common situations: Re-connecting an egui backend IPC client during hot-reload or re-init flows without recreating the Ipc object.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of libnyanpasu/clash-nyanpasu@f7dbce2997 (2026-09-08). Data as JSON: /api/errors/37a9757fb46a3ba4. Report an issue: GitHub.