aaif-goose/goose · error

This window's Goose backend stopped. Close this window and o

Error message

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.

What it means

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.

Source

Thrown at ui/desktop/src/gooseServeLeaseRegistry.ts:100

      windowIds: new Set<number>(),
      cleanedUp: false,
      exited: false,
      exitCode: null,
      exitSignal: null,
    };
  }

  get(windowId: number): GooseServeLease | null {
    return this.leasesByWindowId.get(windowId) ?? null;
  }

  getAcpUrl(windowId: number): string | null {
    const lease = this.get(windowId);
    if (!lease) {
      return null;
    }
    if (lease.exited) {
      throw new Error(GOOSE_SERVE_EXITED_USER_MESSAGE);
    }
    return lease.acpUrl;
  }

  getSecretKey(windowId: number): string | null {
    const lease = this.get(windowId);
    if (!lease) {
      return null;
    }
    if (lease.exited) {
      throw new Error(GOOSE_SERVE_EXITED_USER_MESSAGE);
    }
    return lease.secretKey;
  }

  attachWindow(windowId: number, lease: GooseServeLease) {
    lease.windowIds.add(windowId);
    this.leasesByWindowId.set(windowId, lease);

View on GitHub (pinned to 3810898a74)

Solutions

  1. Catch this error in the IPC handler and surface the message to the renderer so the user closes the window / opens a new chat
  2. Inspect the main-process log for 'Goose ACP server exited unexpectedly' (logged with exit code, signal, windowIds) to find why the process died
  3. If exits recur, check exitCode/signal: non-zero codes point at goose crashes — update the binary or reduce memory pressure; SIGKILL usually means OOM
  4. Ensure releaseWindow is called when windows close so stale exited leases are not reused
Defensive patterns

Strategy: type-guard

Validate before calling

const lease = leaseRegistry.get(windowId);
if (!lease || lease.exited) {
  // surface GOOSE_SERVE_EXITED_USER_MESSAGE or tear down the window; do not call getAcpUrl
}

Type guard

const hasLiveLease = (windowId: number): boolean => {
  const lease = leaseRegistry.get(windowId);
  return lease !== null && !lease.exited;
};

Try / catch

try {
  acpUrl = leaseRegistry.getAcpUrl(windowId);
} catch (e) {
  if (e instanceof Error && e.message === GOOSE_SERVE_EXITED_USER_MESSAGE) {
    return { error: e.message }; // IPC-safe: renderer shows 'open a new chat'
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16). Data as JSON: /api/errors/35ee22ff63193519. Report an issue: GitHub.