{"record":{"id":"b7618ef25ecda340","repo":"slopus/happy","slug":"no-main-session-key-from-gateway","errorCode":null,"errorMessage":"No main session key from gateway","messagePattern":"No main session key from gateway","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/happy-cli/src/openclaw/OpenClawBackend.ts","lineNumber":106,"sourceCode":"    });\n\n    this.socket.onEvent((event, payload) => {\n      this.handleEvent(event, payload);\n    });\n  }\n\n  async startSession(): Promise<StartSessionResult> {\n    this.connectionReady = new Promise<void>((resolve, reject) => {\n      this.connectionResolve = resolve;\n      this.connectionReject = reject;\n    });\n\n    this.socket.connect(this.gatewayConfig);\n    await this.connectionReady;\n\n    this.sessionKey = this.socket.getMainSessionKey();\n    if (!this.sessionKey) {\n      throw new Error('No main session key from gateway');\n    }\n\n    const sessionId = this.sessionKey;\n    this.log(`Session started: ${sessionId}`);\n    return { sessionId };\n  }\n\n  async sendPrompt(sessionId: SessionId, prompt: string): Promise<void> {\n    if (!this.socket.isConnected()) {\n      throw new Error('Not connected to OpenClaw gateway');\n    }\n\n    this.lastDeltaText = null;\n\n    this.turnReady = new Promise<void>((resolve, reject) => {\n      this.turnResolve = resolve;\n      this.turnReject = reject;\n    });","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/slopus/happy/blob/b824cd0a4681d41af631a8e422a813873e4455b0/packages/happy-cli/src/openclaw/OpenClawBackend.ts#L88-L124","documentation":"After connecting to the OpenClaw gateway, startSession() asks the socket for the main session key. The gateway is expected to assign this key during the connection handshake; if getMainSessionKey() returns nothing, happy cannot identify the session and throws. This indicates a protocol-level problem with the gateway connection rather than a local configuration issue.","triggerScenarios":"OpenClawBackend.startSession() calls this.socket.getMainSessionKey() after `await this.connectionReady` and the return value is falsy — the gateway never provided a main session key.","commonSituations":"Connecting to an incompatible or non-standard gateway implementation that omits the main session key in its handshake; gateway version mismatch with the protocol happy expects; gateway crashed mid-handshake while connectionReady still resolved.","solutions":["Verify the gateway version matches what the happy CLI expects (update both openclaw and happy)","Check gateway logs to confirm it sends the main session key during the connection handshake","Restart the gateway and retry; test against a known-good local openclaw instance"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"await backend.start(); // then\nconst key = socket.getMainSessionKey();\nif (!key) throw new Error('Gateway did not provide a main session key');","typeGuard":"const hasSessionKey = (k: string | null | undefined): k is string => typeof k === 'string' && k.length > 0;","tryCatchPattern":"try {\n  const { sessionId } = await backend.startSession();\n} catch (err) {\n  if (err.message === 'No main session key from gateway') {\n    await backend.restart(); // reconnect and re-handshake\n  } else throw err;\n}","preventionTips":["Keep openclaw gateway and happy CLI versions in sync","Verify the gateway handshake payload includes the main session key after upgrades","Restart the gateway when handshake responses look empty"],"tags":["openclaw","gateway","session","protocol"],"backgroundTag":"gateway-handshake-failed","analyzedSha":"b824cd0a4681d41af631a8e422a813873e4455b0","analyzedAt":"2026-08-31T23:12:36.205Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}