Fix #2218: fix: bug: Hermes viewer daemon always reports "occupied" on Windows (connection- - #2220
Conversation
…port probe `_probe_json_url()` only recognised macOS/Linux ECONNREFUSED errno values (61, 111) and the English "connection refused" substring, so on non-English Windows the socket raised errno 10061 with a locale-dependent message (e.g. Czech: "cílový počítač je aktivně odmítl") that matched neither branch. An unused port was therefore always misclassified as "blocked", the viewer daemon never started, and http://127.0.0.1:18800/ was permanently unreachable on fresh non-English Windows installs. Fix: - Add 10061 (WSAECONNREFUSED) to the errno whitelist. - Fall back to `isinstance(reason, ConnectionRefusedError)` — Python raises this type consistently across platforms regardless of errno or locale, and is the load-bearing signal even if errno is missing. Add 6 pytest cases in `ProbeJsonUrlConnectionRefusedTests` covering Windows errno 10061 (English + Czech messages), bare `ConnectionRefusedError`, macOS errno 61, Linux errno 111, and a "must stay blocked" negative case for unrelated OSError. Fixes MemTensor#2218 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
🤖 Open Code ReviewTarget: PR #2220 ✅ OpenCodeReview: No comments generated. Looks good to me. Generated by cloud-assistant via Open Code Review. |
🔧 Open Code Review requested Agent fixOpen Code Review found 1 issue(s). I have resumed the development Agent to fix them.
The Agent will push a new commit to this PR branch. OCR will recheck after the commit is pushed. |
Address OCR finding on PR MemTensor#2220: `_run_probe` in `ProbeJsonUrlConnectionRefusedTests` was annotated `-> object`, which is uninformative. The helper always patches `urlopen` with a `side_effect=urlerror`, so `_probe_json_url` only ever reaches its `URLError` branches, all of which return `"free"` or `"blocked"`. All six test assertions compare the result against string literals. `-> str` makes the intent explicit and lets type checkers catch any accidental future change to a non-string return. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
✅ Automated Test Results: PASSEDAll tests passed (69/69 executed). memos_local_plugin/changed-repo-python: 60/60, memos_python_core/changed-repo-python: 9/9. Duration: 7s Branch: |
|
Synced this PR with the latest I independently reproduced the original regression on the target branch: a localized Local verification on
A fresh Python Actions run was triggered: https://github.com/MemTensor/MemOS/actions/runs/31122324729. OCR/AutoTest statuses have not appeared yet. GitHub currently reports a major Actions outage, so this run may remain queued until the platform recovers. |
Description
Fix #2218: Hermes viewer daemon now correctly detects a free port on non-English Windows. Root cause was
_probe_json_url()inapps/memos-local-plugin/adapters/hermes/memos_provider/daemon_manager.pyrecognising only macOS/Linux ECONNREFUSED errno values (61, 111) and the English "connection refused" substring; Windows raises errno 10061 (WSAECONNREFUSED) with a locale-dependent message (e.g. Czech "cílový počítač je aktivně odmítl") that matched neither branch, so an unused port was permanently misclassified as "blocked" and the viewer panel at http://127.0.0.1:18800/ never launched.Fix (2 files, +86/-1 lines): (1)
daemon_manager.py::_probe_json_url()— added 10061 to the errno whitelist and addedisinstance(reason, ConnectionRefusedError)as a locale-agnostic type check that is load-bearing when errno is missing. (2)tests/python/test_bridge_client.py— addedProbeJsonUrlConnectionRefusedTests(6 cases): Windows errno 10061 with English + Czech messages, bare ConnectionRefusedError, macOS errno 61 (regression), Linux errno 111 (regression), and a "must stay blocked" negative case for unrelated OSError. All three Windows-related tests were red BEFORE the fix (bug reproduced) and green after.Verification on the pushed HEAD:
python3 -m unittest tests.python.test_bridge_client.ProbeJsonUrlConnectionRefusedTests tests.python.test_bridge_client.ViewerDaemonTests tests.python.test_bridge_client.BridgeOkCacheTests→ 17/17 pass.python3 -m ruff check+python3 -m ruff format --checkon both changed files → all clean. Live-fire cross-platform simulation confirms all six scenarios classify correctly.Scope: bug quick-fix in one function of one file plus its unit tests; no schema, API contract, pyproject, or public interface change.
.ai-tasks/2026-08-05-2218-...mdand the mirrored task.md in the specs repo document the requirement clarification, root cause, and phase progress.Related Issue (Required): Fixes #2218
Type of change
Please delete options that are not relevant.
How Has This Been Tested?
Not run; documentation-only change.
Checklist
@whipser030, @hijzy please review this PR.
Reviewer Checklist