{"record":{"id":"35ee22ff63193519","repo":"aaif-goose/goose","slug":"this-window-s-goose-backend-stopped-close-this-wi","errorCode":null,"errorMessage":"This window's Goose backend stopped. Close this window and open a new chat to start a new backend. If this keeps happening, restart Goose Desktop.","messagePattern":"This window's Goose backend stopped\\. Close this window and open a new chat to start a new backend\\. If this keeps happening, restart Goose Desktop\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"ui/desktop/src/gooseServeLeaseRegistry.ts","lineNumber":100,"sourceCode":"      windowIds: new Set<number>(),\n      cleanedUp: false,\n      exited: false,\n      exitCode: null,\n      exitSignal: null,\n    };\n  }\n\n  get(windowId: number): GooseServeLease | null {\n    return this.leasesByWindowId.get(windowId) ?? null;\n  }\n\n  getAcpUrl(windowId: number): string | null {\n    const lease = this.get(windowId);\n    if (!lease) {\n      return null;\n    }\n    if (lease.exited) {\n      throw new Error(GOOSE_SERVE_EXITED_USER_MESSAGE);\n    }\n    return lease.acpUrl;\n  }\n\n  getSecretKey(windowId: number): string | null {\n    const lease = this.get(windowId);\n    if (!lease) {\n      return null;\n    }\n    if (lease.exited) {\n      throw new Error(GOOSE_SERVE_EXITED_USER_MESSAGE);\n    }\n    return lease.secretKey;\n  }\n\n  attachWindow(windowId: number, lease: GooseServeLease) {\n    lease.windowIds.add(windowId);\n    this.leasesByWindowId.set(windowId, lease);","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/ui/desktop/src/gooseServeLeaseRegistry.ts#L82-L118","documentation":"The lease registry maps each renderer window to its goose serve lease. getAcpUrl(windowId) throws GOOSE_SERVE_EXITED_USER_MESSAGE when the lease exists but its backing `goose serve` process has exited (the lease's 'exit' listener fired or hasExited() was true at creation). It is a user-facing message by design: the window must be closed and a new chat opened to spawn a fresh backend.","triggerScenarios":"The ACP server process crashes or is killed (OOM, signal, panic) after the window connected; shutdown initiated while a renderer still calls getAcpUrl; any IPC handler that resolves the backend URL for a window whose process died between calls.","commonSituations":"Backend segfault or panic mid-session; user's machine suspends and the child is reaped; antivirus or process cleaners killing goose; tests that stop the serve process then keep using the registry.","solutions":["Catch this error in the IPC handler and surface the message to the renderer so the user closes the window / opens a new chat","Inspect the main-process log for 'Goose ACP server exited unexpectedly' (logged with exit code, signal, windowIds) to find why the process died","If exits recur, check exitCode/signal: non-zero codes point at goose crashes — update the binary or reduce memory pressure; SIGKILL usually means OOM","Ensure releaseWindow is called when windows close so stale exited leases are not reused"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"const lease = leaseRegistry.get(windowId);\nif (!lease || lease.exited) {\n  // surface GOOSE_SERVE_EXITED_USER_MESSAGE or tear down the window; do not call getAcpUrl\n}","typeGuard":"const hasLiveLease = (windowId: number): boolean => {\n  const lease = leaseRegistry.get(windowId);\n  return lease !== null && !lease.exited;\n};","tryCatchPattern":"try {\n  acpUrl = leaseRegistry.getAcpUrl(windowId);\n} catch (e) {\n  if (e instanceof Error && e.message === GOOSE_SERVE_EXITED_USER_MESSAGE) {\n    return { error: e.message }; // IPC-safe: renderer shows 'open a new chat'\n  }\n  throw e;\n}","preventionTips":["Check lease.exited before every getAcpUrl/getSecretKey call in IPC handlers","Subscribe to process 'exit' on the lease to proactively notify the window instead of failing on next request","Always pair attachWindow with releaseWindow so exited leases are never reused"],"tags":["process-lifecycle","electron","ipc","goose-serve","user-facing"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}