{"record":{"id":"c01e88bb998a286b","repo":"can1357/oh-my-pi","slug":"session-cannot-accept-launch-completion-delivery","errorCode":null,"errorMessage":"Session cannot accept launch completion delivery","messagePattern":"Session cannot accept launch completion delivery","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/hub/launch.ts","lineNumber":77,"sourceCode":"\towner: string,\n): CompletionLease | undefined {\n\tif (!session.queueLaunchCompletion) return undefined;\n\tlet clients = completionRegistrations.get(session);\n\tif (!clients) {\n\t\tclients = new Map();\n\t\tcompletionRegistrations.set(session, clients);\n\t}\n\tlet owners = clients.get(client);\n\tif (!owners) {\n\t\towners = new Map();\n\t\tclients.set(client, owners);\n\t}\n\tlet registration = owners.get(owner);\n\tif (!registration) {\n\t\tconst unregister = client.onCompletion(owner, notification => {\n\t\t\tif (session.isDisposed?.()) throw new Error(\"Session disposed before launch completion delivery\");\n\t\t\tconst delivery = session.queueLaunchCompletion?.(notification);\n\t\t\tif (!delivery) throw new Error(\"Session cannot accept launch completion delivery\");\n\t\t\treturn delivery;\n\t\t});\n\t\tlet unregisterDispose: (() => void) | void;\n\t\tlet unregisterSessionChange: (() => void) | void;\n\t\tconst cleanup = (preservePending = false): void => {\n\t\t\tif (!registration?.active) return;\n\t\t\tregistration.active = false;\n\t\t\tunregister({ preservePending });\n\t\t\tunregisterDispose?.();\n\t\t\tunregisterSessionChange?.();\n\t\t\towners.delete(owner);\n\t\t\tif (owners.size === 0) clients.delete(client);\n\t\t\tif (clients.size === 0) completionRegistrations.delete(session);\n\t\t};\n\t\tregistration = { inFlight: 0, retained: false, active: true, cleanup };\n\t\towners.set(owner, registration);\n\t\tunregisterDispose = session.registerDisposeCallback?.(() => cleanup(true));\n\t\tunregisterSessionChange = session.registerSessionChangeCallback?.(() => cleanup(true));","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/hub/launch.ts#L59-L95","documentation":"The launch completion sink throws this when the notification arrives on a live session but `session.queueLaunchCompletion` is missing or returns falsy — the session exists but cannot accept the queued completion. Either the optional method is absent on this session implementation or it refuses the delivery (e.g. wrong owner or already drained).","triggerScenarios":"client.onCompletion callback fires with a live session, but `session.queueLaunchCompletion?.(notification)` is undefined — either the session type lacks queueLaunchCompletion (optional-call `?.`) or it returns null/undefined for the notification.","commonSituations":"Embedding the tool against a custom/trimmed ToolSession implementation that never implemented queueLaunchCompletion; session already processed or invalidated the launch so it declines queuing; version mismatch between the hub tool code and the session object passed in.","solutions":["Ensure the ToolSession passed to the launch tool implements queueLaunchCompletion(notification) and returns a truthy delivery.","Update the session implementation / hub tool so both sides agree on the launch-completion contract.","Check that the launch was not already resolved/drained by another path before the notification arrived."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"// Verify the session supports launch completions before using the launch tool:\nif (typeof session.queueLaunchCompletion !== \"function\") {\n  throw new Error(\"session does not support launch completion delivery\");\n}","typeGuard":"function supportsLaunchCompletion(s: ToolSession): boolean {\n  return typeof (s as ToolSession).queueLaunchCompletion === \"function\";\n}","tryCatchPattern":"try {\n  await launchTool.run({ op: \"start\", name, application });\n} catch (err) {\n  if (err instanceof Error && err.message === \"Session cannot accept launch completion delivery\") {\n    // use/upgrade a session implementation with queueLaunchCompletion support\n  } else throw err;\n}","preventionTips":["Ensure the ToolSession implementation fully implements the hub launch contract.","Keep session and hub tool versions in sync.","Avoid draining/resolving launches on a second path before the notification arrives."],"tags":["api-contract","session","integration"],"backgroundTag":"session-capability-missing","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}