Skip to content

fix(cli): restart daemon when console requested host/port don't match - #11138

Merged
catrielmuller merged 9 commits into
Kilo-Org:mainfrom
IamCoder18:cli-console-restart-on-port-mismatch
Jun 12, 2026
Merged

fix(cli): restart daemon when console requested host/port don't match#11138
catrielmuller merged 9 commits into
Kilo-Org:mainfrom
IamCoder18:cli-console-restart-on-port-mismatch

Conversation

@IamCoder18

Copy link
Copy Markdown
Contributor

Issue

Fixes #11137

Context

kilo console with explicit --port or --hostname options silently reuses a running daemon on a different host/port, ignoring the user's request. Since the server binds once at startup, there is no way to change the bind address of a running process — a restart is required.

Implementation

Extracted daemon startup logic into an exported startDaemon helper that checks whether the returned state is a reuse and whether it differs from the requested options. When a mismatch is detected and restartOnMismatch is true, it logs a warning, calls Daemon.stop(), and restarts with Daemon.start(opts).

The restartOnMismatch flag is only enabled when explicit --port or --hostname CLI arguments are detected in process.argv, preventing unnecessary restarts when the user runs kilo console without flags (which defaults to port 0 for auto-assignment).

Also added tests to verify functionality in the future.

Key design decisions:

  • Port mismatch ignores opts.port === 0 (auto-port) to avoid restarts on default invocations

Screenshots / Video

before after
image image

How to Test

Manual/local verification

  • kilo console --port 4097 starts daemon on 4097, then kilo console --port 4321 shows a warning and restarts on 4321
  • kilo console without flags reuses the existing daemon without restarting

Reviewer test steps

  1. Run kilo daemon stop to ensure clean state
  2. Run kilo console --port 4097 — confirm URL shows port 4097
  3. Run kilo console --port 4321 — confirm a warning is printed, daemon restarts, and URL shows port 4321
  4. Run kilo console — confirm it reuses the daemon on port 4321 without restarting

Checklist

  • Issue linked above, or exception explained
  • Tests/verification described
  • Screenshots/video included for visual changes, or marked N/A
  • Changeset considered for user-facing changes
  • I personally reviewed the diff and can explain the changes, including any AI-assisted work.

Get in Touch

Discord: @IamCoder18

Comment thread packages/opencode/src/kilocode/cli/cmd/console.ts Outdated
Comment thread packages/opencode/test/kilocode/cli/cmd/console.test.ts Outdated
Comment thread packages/opencode/test/kilocode/cli/cmd/console.test.ts Outdated
@kilo-code-bot

kilo-code-bot Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Resolved Issues (from previous reviews)
  • Manual stop+start bypasses Daemon.restart() — Resolved. console.ts and daemon.ts now call Daemon.ensure(), which uses the internal run() helper with the flock — no separate stop+start.
  • TOCTOU race — freePort()/port() releases the probed port before daemon binds it — Resolved. The freePort()/port() helpers are gone entirely. The test file is now pure unit tests with no live port probing.
  • afterEach guard concern — Resolved. The afterEach and env-restore teardown are gone; the new tests are synchronous unit tests with no process state.
  • All other previously raised issues remain resolved.
What changed in this update
  • daemon.ts: Added Network Zod schema (with cors dedup+sort normalization), persists options in daemon state, extracts internal run() helper, adds matches() and ensure() exports, fixes restart() to run inside the lock, adds KILO_TEST_DAEMON_EPHEMERAL_PORT escape hatch in port() so tests use OS-assigned ports.
  • console.test.ts: Completely replaced live integration tests with synchronous unit tests for Daemon.matches() and explicitNetworkOptions(). No live daemon processes, no TOCTOU risk.
  • daemon.test.ts: Adds KILO_TEST_DAEMON_EPHEMERAL_PORT: "1" to test env so the live daemon test uses an OS-assigned port; loosens port assertion from range check to > 0.
Files Reviewed (5 files)
  • packages/opencode/src/kilocode/cli/cmd/console.ts — uses Daemon.ensure() correctly
  • packages/opencode/src/kilocode/cli/cmd/daemon.ts — uses Daemon.ensure() correctly, correct 3-way message
  • packages/opencode/src/kilocode/daemon/daemon.tsmatches(), ensure(), run() logic all correct; cors normalization and vacuous-truth for empty explicit list handled properly
  • packages/opencode/test/kilocode/cli/cmd/console.test.ts — unit tests cover all match/mismatch/legacy-state cases
  • packages/opencode/test/kilocode/daemon.test.ts — ephemeral port env var correctly propagated; loosened assertion is appropriate

Reviewed by claude-4.6-sonnet-20260217 · 1,048,861 tokens

Review guidance: REVIEW.md from base branch main

@IamCoder18
IamCoder18 force-pushed the cli-console-restart-on-port-mismatch branch 3 times, most recently from b02dfd3 to 8609707 Compare June 12, 2026 01:12
Comment thread packages/opencode/test/kilocode/cli/cmd/console.test.ts Outdated
When `kilo console --port 4321` reuses an already-running daemon on a

different port (e.g. 4097), the new options were silently ignored. Now

`kilo console` checks if the running daemon matches the requested

host/port, and restarts if they differ.

The restart only occurs when explicit `--port` or `--hostname` options

are provided via CLI, not when using default values.
@IamCoder18
IamCoder18 force-pushed the cli-console-restart-on-port-mismatch branch from 8609707 to 63294a4 Compare June 12, 2026 01:51
}
}

async function port() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

WARNING: TOCTOU race — port() closes the server before the daemon binds it

The helper probes an OS-assigned free port by listening on port 0, then immediately closes the server and returns the port number. Between server.close() completing and the daemon calling bind(), another process (or another concurrent test) can grab that port. On a loaded CI host this is a low-probability but real flake source.

The port: 0 auto-assign path used elsewhere (e.g. lines 92, 111) avoids this entirely — the OS holds the binding until listen() succeeds. If the test genuinely needs to verify that the daemon binds a specific user-supplied port, consider passing port: 0 and then asserting result.state.port !== 0, or accept the small risk given the narrow test-only scope.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

@catrielmuller
catrielmuller merged commit b38f87a into Kilo-Org:main Jun 12, 2026
18 checks passed
t7tran pushed a commit to t7tran/kilocode that referenced this pull request Aug 14, 2026
…-on-port-mismatch

fix(cli): restart daemon when console requested host/port don't match
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.

kilo console with explicit --port or --hostname ignores mismatched running daemon

2 participants