Skip to content

fix(devframe): listen on both loopback addresses for a localhost side-car - #462

Open
onmax wants to merge 1 commit into
devframes:mainfrom
onmax:fix/sidecar-localhost-both-loopbacks
Open

onmax wants to merge 1 commit into
devframes:mainfrom
onmax:fix/sidecar-localhost-both-loopbacks

Conversation

@onmax

@onmax onmax commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

A page on 127.0.0.1 cannot connect to a side-car on the default localhost host:

WebSocket connection to 'ws://127.0.0.1:9777/__ws' failed: net::ERR_CONNECTION_REFUSED

The client dials the side-car on the page hostname. The side-car calls listen(port, 'localhost'), and Node binds only one address. On current Linux and macOS, that address is ::1. Nuxt DevTools 4 has this problem with nuxt dev --host 127.0.0.1.

Repro: onmax/repros devframe-localhost-sidecar. Run pnpm install && pnpm test.

Now a localhost side-car also listens on the other loopback address, on the same port. If a different process holds that address, the side-car moves to a new port.

Check Before After
Page on 127.0.0.1 connects, 2 Nuxt apps 0 of 2 2 of 2
New side-car tests 2 fail 2 pass
devframe tests 676 of 676 pass

…-car

A page on 127.0.0.1 could not reach a side-car on the default localhost
host. The client dials the page hostname, but listen(port, 'localhost')
binds only the first address localhost resolves to (::1 on current
Linux and macOS).
@vercel

vercel Bot commented Oct 26, 2026

Copy link
Copy Markdown

@onmax is attempting to deploy a commit to the NuxtLabs Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions

Copy link
Copy Markdown

👁️‍🗨️ Review this pull request with grouped, summarized diffs at:
👉 https://pulls.review/gh/devframes/devframe/462?from=github-actions[bot]

raw result

💭 analyzed by vercel-ai-gateway/anthropic/claude-sonnet-5
🕰️ 2026-10-26 20:03 UTC
🔗 head 3e5f0d1
🤖 automated by pulls.review

{
  "headSha": "3e5f0d10874de7c03bce3b20d0b4555292335f74",
  "result": {
    "overallSummary": "Fixes a bug where a side-car WebSocket server bound only to `localhost`'s first-resolved loopback address (typically `::1`), leaving pages opened on `127.0.0.1` unable to connect. The side-car now also binds the other loopback address and forwards traffic to the main server, with tests and docs updated accordingly.",
    "groups": [
      {
        "key": "loopback-twin-fix",
        "label": "Loopback twin listener fix",
        "summary": "When the side-car host is `localhost`, it now also binds the other loopback address (`127.0.0.1` or `::1`) on the same port and forwards requests/upgrades to the main server, so pages opened on either loopback address can connect. If another process already holds the twin address, binding fails like a taken port; if the OS lacks that address family, the twin is simply skipped.",
        "category": "core",
        "filePaths": [
          "packages/devframe/src/node/instance-shell.ts"
        ],
        "critical": true,
        "lineNotes": [
          {
            "path": "packages/devframe/src/node/instance-shell.ts",
            "side": "additions",
            "line": 118,
            "text": "If the twin bind fails for a reason other than a missing address family (e.g. another process already owns that address/port), the main server is closed and the error propagates, so a page on that address never silently reaches a different server.",
            "critical": true
          }
        ]
      },
      {
        "key": "tests",
        "label": "Side-car loopback tests",
        "summary": "Adds tests verifying that a `localhost` side-car is reachable on both `127.0.0.1` and `[::1]`, and that it moves to a new port when another process already holds the twin loopback address on the original port.",
        "category": "tests",
        "filePaths": [
          "packages/devframe/src/adapters/__tests__/initiate.test.ts"
        ]
      },
      {
        "key": "docs",
        "label": "Docs update",
        "summary": "Documents that a `localhost` side-car listens on both loopback addresses so pages opened on either one can reach it.",
        "category": "docs",
        "filePaths": [
          "docs/content/2.adapters/1.initiate.md"
        ]
      }
    ],
    "schemaVersion": 1,
    "source": "llm",
    "generatedAt": "2026-10-26T20:03:27.071Z",
    "model": "vercel-ai-gateway/anthropic/claude-sonnet-5",
    "locale": "en"
  }
}

This branch has not been deployed

No deployments
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.

1 participant