{"record":{"id":"ead2e88c2d3e9441","repo":"can1357/oh-my-pi","slug":"daemon-broker-request-aborted","errorCode":null,"errorMessage":"Daemon broker request aborted","messagePattern":"Daemon broker request aborted","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"packages/coding-agent/src/launch/client.ts","lineNumber":165,"sourceCode":"\treadonly #inFlightCompletionIds = new Set<string>();\n\treadonly #completionSubscriptionId = crypto.randomUUID();\n\t#socket: net.Socket | undefined;\n\t#connectPromise: Promise<void> | undefined;\n\t#buffer = \"\";\n\t#closed = false;\n\t#completionReconnectTimer: NodeJS.Timeout | undefined;\n\n\tconstructor(projectDir: string, runtimeDir: string, token: string, options: DaemonBrokerClientOptions) {\n\t\tthis.projectDir = projectDir;\n\t\tthis.#runtimeDir = runtimeDir;\n\t\tthis.#endpoint = daemonBrokerEndpoint(projectDir, runtimeDir);\n\t\tthis.#token = token;\n\t\tthis.#idleGraceMs = options.idleGraceMs;\n\t}\n\n\tasync request(operation: DaemonOperation, signal?: AbortSignal): Promise<DaemonRpcResult> {\n\t\tif (this.#closed) throw new Error(\"Daemon broker client is closed\");\n\t\tif (signal?.aborted) throw new Error(\"Daemon broker request aborted\");\n\t\tawait this.#connect();\n\t\tconst socket = this.#socket;\n\t\tif (!socket || socket.destroyed) throw new Error(\"Daemon broker socket is unavailable\");\n\n\t\tconst completionUnsubscribes = [...this.#completionUnsubscribes];\n\t\tconst completionReplays = [...this.#completionReplays];\n\t\tconst id = crypto.randomUUID();\n\t\tconst { promise, resolve, reject } = Promise.withResolvers<DaemonRpcResult>();\n\t\tconst timer = setTimeout(() => {\n\t\t\tconst pending = this.#pending.get(id);\n\t\t\tif (!pending) return;\n\t\t\tthis.#pending.delete(id);\n\t\t\tpending.removeAbort?.();\n\t\t\treject(new Error(`Daemon ${operation.op} request timed out`));\n\t\t}, requestTimeoutMs(operation));\n\t\tconst pending: PendingRequest = { operation, resolve, reject, timer };\n\t\tif (signal) {\n\t\t\tconst abort = (): void => {","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/launch/client.ts#L147-L183","documentation":"request() rejects immediately if the caller-supplied AbortSignal is already aborted, before attempting a connection. This signals that the operation was cancelled before it started, so no RPC is sent and no socket is opened.","triggerScenarios":"Passing an AbortSignal that was aborted earlier (e.g. a timeout that fired during prior awaits, or a user cancellation) into DaemonBrokerClient.request().","commonSituations":"Racing request timeouts; user cancels an action whose completion publish still runs; reusing one AbortController for a whole batch after one item failed.","solutions":["Check signal.aborted before calling request and skip the call gracefully","Create a fresh AbortController per request rather than sharing one across a sequence","Handle AbortError-style failures in callers of #publishCompletionOwners so cancellation is expected, not exceptional"],"exampleFix":"// before\nawait client.request(op, signal);\n// after\nif (signal?.aborted) return;\nawait client.request(op, signal);","handlingStrategy":"validation","validationCode":"if (signal?.aborted) return; // or throw a typed cancellation before calling request","typeGuard":null,"tryCatchPattern":"try {\n  await client.request(op, signal);\n} catch (err) {\n  if (err.message === 'Daemon broker request aborted') return; // expected cancellation, not a failure\n  throw err;\n}","preventionTips":["Use a fresh AbortController per logical request instead of sharing one","Check signal.aborted at each await boundary in multi-step flows","Treat aborted-signal errors as control flow, not faults"],"tags":["ipc","abort","cancellation"],"backgroundTag":"operation-aborted","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}