{"record":{"id":"1d9e6ca0a99a389f","repo":"stablyai/orca","slug":"daemon-client-connection-is-incomplete-reconnect","errorCode":null,"errorMessage":"Daemon client connection is incomplete; reconnect","messagePattern":"Daemon client connection is incomplete; reconnect","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"src/main/daemon/daemon-server.ts","lineNumber":945,"sourceCode":"  }\n\n  private cancelPendingPtySpawnPreparationsForClient(clientId: string): void {\n    for (const pending of this.pendingPtySpawnPreparations.values()) {\n      for (const preparation of pending) {\n        if (preparation.clientId === clientId) {\n          preparation.canceled = true\n        }\n      }\n    }\n  }\n\n  private async routeRequest(clientId: string, request: DaemonRequest): Promise<unknown> {\n    const client = this.clients.get(clientId)\n\n    switch (request.type) {\n      case 'startHistorySeedTransfer': {\n        if (!client?.authenticatedPairEstablished || client.streamSocket === null) {\n          throw new Error('Daemon client connection is incomplete; reconnect')\n        }\n        const transferId = this.historySeedTransfers.start(clientId, request.payload)\n        return { transferId }\n      }\n\n      case 'appendHistorySeedTransfer':\n        this.historySeedTransfers.append(\n          clientId,\n          request.payload.transferId,\n          request.payload.index,\n          request.payload.data\n        )\n        return {}\n\n      case 'finishHistorySeedTransfer':\n        this.historySeedTransfers.finish(clientId, request.payload.transferId)\n        return {}\n","sourceCodeStart":927,"sourceCodeEnd":963,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/daemon/daemon-server.ts#L927-L963","documentation":"In routeRequest, startHistorySeedTransfer (and createOrAttach, and others) require the client to have both authenticatedPairEstablished and a non-null streamSocket. A control-only replacement connection — one that authenticated the control channel but has not paired a data stream — cannot own terminal admission or history seeds, so the daemon throws a plain Error('Daemon client connection is incomplete; reconnect').","triggerScenarios":"Client sent the RPC before establishing the stream channel pairing; the stream socket disconnected and a replacement control connection took over but the new stream pair is still pending; a buggy client that tries history-seed transfer or createOrAttach before hello/pair completes.","commonSituations":"Reconnect races where control re-establishes faster than stream; a client downgrade that skips the pairing step; transient stream drop mid-session with the renderer retrying immediately.","solutions":["On the client, await the full pairing (control + stream) before issuing startHistorySeedTransfer or createOrAttach.","Treat the message as a soft signal to reconnect: tear down and re-establish both channels, then retry.","Audit the client connection handshake to confirm authenticatedPairEstablished only flips after the stream socket is set."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":"function isIncompleteClientConnection(e: unknown): boolean {\n  return e instanceof Error && e.message === 'Daemon client connection is incomplete; reconnect'\n}","tryCatchPattern":"try {\n  await daemon.createOrAttach(payload)\n} catch (e) {\n  if (isIncompleteClientConnection(e)) {\n    // tear down both channels, re-establish control + stream pairing, then retry\n  } else throw e\n}","preventionTips":["Await the full control+stream pairing before issuing createOrAttach or history-seed transfers.","Confirm the client sets authenticatedPairEstablished only after streamSocket is non-null.","On reconnect, fully reset both channels rather than reusing a half-open one."],"tags":["daemon","client","handshake","reconnect","wire"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}