Skip to content

fix: guard against null socket/encryption — 'undefined is not a function'#907

Open
chris-yyau wants to merge 1 commit intoslopus:mainfrom
chris-yyau:fix/socket-null-guards-906
Open

fix: guard against null socket/encryption — 'undefined is not a function'#907
chris-yyau wants to merge 1 commit intoslopus:mainfrom
chris-yyau:fix/socket-null-guards-906

Conversation

@chris-yyau
Copy link

Summary

Fixes intermittent "undefined is not a function" crashes caused by calling methods on null socket/encryption references after WebSocket disconnects.

  • apiSocket.ts: Replace this.socket! / this.encryption! non-null assertions with explicit null guards using local variable capture to prevent TOCTOU races across await yield points
  • happyMcpStdioBridge.ts: Add promise lock with try/finally to prevent concurrent ensureHttpClient() calls from creating duplicate MCP clients
  • startHappyServer.ts: Add server.on('error') handler with logging so port conflicts reject instead of hanging

Test plan

  • change_title MCP tool works normally
  • App shows "Socket not connected" error instead of crashing on disconnect
  • Concurrent change_title calls don't create duplicate clients

🤖 Generated with Claude Code via Happy

…t a function"

Three fixes for intermittent "undefined is not a function" crashes:

1. **apiSocket.ts**: Replace non-null assertions (`this.socket!`, `this.encryption!`)
   with explicit null checks using local variable capture to prevent TOCTOU
   races across `await` boundaries. Throws descriptive errors instead of crashing.

2. **happyMcpStdioBridge.ts**: Add promise lock to `ensureHttpClient()` with
   `try/finally` cleanup to prevent race conditions and stale rejected promises.

3. **startHappyServer.ts**: Add missing error handler on HTTP server binding.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Copilot AI review requested due to automatic review settings March 24, 2026 12:34
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the Happy app/CLI against intermittent crashes and hangs caused by stale/null references during disconnects and by concurrent initialization paths.

Changes:

  • Add explicit null guards and local socket capture in ApiSocket RPC/send paths to prevent “undefined is not a function” after disconnects.
  • Serialize MCP HTTP client creation in the STDIO bridge using a shared connectPromise to prevent duplicate clients under concurrent tool calls.
  • Reject startHappyServer() startup on server error events so port/bind failures don’t hang silently.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
packages/happy-cli/src/codex/happyMcpStdioBridge.ts Adds a promise-based lock to prevent concurrent MCP client creation.
packages/happy-cli/src/claude/utils/startHappyServer.ts Adds an error listener to reject server startup on bind/listen failures.
packages/happy-app/sources/sync/apiSocket.ts Replaces non-null assertions with runtime guards and safer socket usage across await.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants