{"record":{"id":"e23bea3370e9b6c2","repo":"stablyai/orca","slug":"remote-connection-dropped-click-reconnect-on-the-e23bea","errorCode":null,"errorMessage":"Remote connection dropped. Click Reconnect on the SSH target before retrying.","messagePattern":"Remote connection dropped\\. Click Reconnect on the SSH target before retrying\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/ipc/git-status-upstream-ref-watch-request.ts","lineNumber":45,"sourceCode":"\nexport function applyGitStatusUpstreamRefWatchRequest(\n  store: Store,\n  args: GitStatusUpstreamRefWatchRequest\n): Promise<void> {\n  const providerGeneration = args.connectionId\n    ? getSshGitProviderGeneration(args.connectionId)\n    : undefined\n  return setWorktreeGitStatusRefWatch(\n    { ...args, ...(providerGeneration !== undefined ? { providerGeneration } : {}) },\n    async (bindingSignal) => {\n      if (!args.branch || !args.upstreamName) {\n        return undefined\n      }\n      const signal = boundedSignal(bindingSignal)\n      if (args.connectionId) {\n        const provider = getSshGitProvider(args.connectionId)\n        if (!provider) {\n          throw new Error(SSH_GIT_PROVIDER_UNAVAILABLE_MESSAGE)\n        }\n        return resolveGitStatusUpstreamRef(\n          (gitArgs, cwd, requestSignal) =>\n            provider.exec(gitArgs, cwd, {\n              signal: requestSignal,\n              timeoutMs: UPSTREAM_REF_RESOLUTION_TIMEOUT_MS\n            }),\n          args.worktreePath,\n          args.branch,\n          args.upstreamName,\n          signal\n        )\n      }\n\n      const worktreePath = await resolveRegisteredWorktreePath(args.worktreePath, store)\n      const repo = getLocalRepoForRegisteredWorktree(store, args.worktreePath, worktreePath)\n      const gitOptions = getLocalGitOptionsForRepo(store, repo)\n      return resolveGitStatusUpstreamRef(","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/ipc/git-status-upstream-ref-watch-request.ts#L27-L63","documentation":"Thrown inside the upstream-ref watch resolver (setWorktreeGitStatusRefWatch binding) when args.connectionId is set but getSshGitProvider returns undefined. Unlike the one-shot handlers, this is a long-lived watch: a providerGeneration is captured at setup, and if the relay session drops before the watch resolves resolveGitStatusUpstreamRef, the provider lookup at git-status-upstream-ref-watch-request.ts:45 fails. The watch then surfaces this error to its consumer.","triggerScenarios":"A worktree git-status upstream ref watch is established for a remote worktree (args.branch and args.upstreamName both set, connectionId set). The SSH relay session disconnects between watch registration and ref resolution (or mid-watch on a refresh), so getSshGitProvider(args.connectionId) is undefined when the binding callback runs.","commonSituations":"Status bar polling an upstream ref on a remote worktree when the SSH session idle-times-out or the network flaps; reconnect incremented the provider generation, invalidating the captured binding; relay restarted while the watch was active.","solutions":["Reconnect the SSH target so a new provider (new generation) registers, then let the watch re-subscribe.","Ensure the watch consumer reacts to a generation change / provider-unavailable result by re-binding rather than leaving a stale watch.","Raise SSH keepalive to keep long-lived watches alive.","Treat the provider-unavailable result as a transient watch error and re-establish after reconnect instead of surfacing a hard failure."],"exampleFix":"// before — watch fires blindly even when provider dropped mid-binding\nprovider = getSshGitProvider(args.connectionId)\nif (!provider) { throw new Error(SSH_GIT_PROVIDER_UNAVAILABLE_MESSAGE) }\n\n// after — treat as transient: re-bind watch on next generation after reconnect\nif (!provider) {\n  requestWatchRebindOnReconnect(args.connectionId)\n  return undefined\n}","handlingStrategy":"validation","validationCode":"// In the watch binding: if the provider dropped mid-watch, signal rebind instead of throwing\nconst provider = getSshGitProvider(args.connectionId)\nif (!provider) {\n  return { kind: 'provider-unavailable', connectionId: args.connectionId }\n}","typeGuard":"export function hasLiveSshProvider(connectionId?: string): connectionId is string {\n  return typeof connectionId === 'string' && getSshGitProvider(connectionId) !== undefined\n}","tryCatchPattern":"// Watch consumer: treat provider-unavailable as transient, rebind after reconnect\ntry {\n  result = await resolveUpstreamRefWatch(args)\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Remote connection dropped')) {\n    scheduleWatchRebindOnReconnect(args.connectionId)\n    return\n  }\n  throw e\n}","preventionTips":["Capture providerGeneration at watch setup and re-bind when it changes (reconnect increments it).","Treat a missing provider inside a long-lived watch as transient — re-subscribe after reconnect rather than hard-failing.","Invalidate watches on connection-drop events.","Keep SSH keepalive stable so long-lived upstream-ref watches survive."],"tags":["ssh","git","remote","ipc","watch","connection-state"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}