Skip to content

Fix #2218: fix: bug: Hermes viewer daemon always reports "occupied" on Windows (connection- - #2220

Closed
Memtensor-AI wants to merge 3 commits into
MemTensor:dev-v2.0.29from
Memtensor-AI:bugfix/autodev-2218-20260805062958307
Closed

Fix #2218: fix: bug: Hermes viewer daemon always reports "occupied" on Windows (connection-#2220
Memtensor-AI wants to merge 3 commits into
MemTensor:dev-v2.0.29from
Memtensor-AI:bugfix/autodev-2218-20260805062958307

Conversation

@Memtensor-AI

Copy link
Copy Markdown
Collaborator

Description

Fix #2218: Hermes viewer daemon now correctly detects a free port on non-English Windows. Root cause was _probe_json_url() in apps/memos-local-plugin/adapters/hermes/memos_provider/daemon_manager.py recognising 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 added isinstance(reason, ConnectionRefusedError) as a locale-agnostic type check that is load-bearing when errno is missing. (2) tests/python/test_bridge_client.py — added ProbeJsonUrlConnectionRefusedTests (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 --check on 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-...md and 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.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (does not change functionality, e.g. code style improvements, linting)
  • Documentation update

How Has This Been Tested?

Not run; documentation-only change.

  • Unit Test
  • Test Script Or Test Steps (please provide)
  • Pipeline Automated API Test (please provide)

Checklist

  • I have performed a self-review of my own code
  • I have commented my code in hard-to-understand areas
  • I have added tests that prove my fix is effective or that my feature works
  • I have created related documentation issue/PR in MemOS-Docs (if applicable)
  • I have linked the issue to this PR (if applicable)
  • I have mentioned the person who will review this PR

@whipser030, @hijzy please review this PR.

Reviewer Checklist

…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>
@Memtensor-AI Memtensor-AI added ai:generated Generated or modified by AI | 由 AI 生成或修改 area:plugin OpenClaw & Hermes status:in-progress Someone or AI is working on it | 人工或 AI 正在处理 labels Aug 5, 2026
@Memtensor-AI

Memtensor-AI commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator Author

🤖 Open Code Review

Target: PR #2220
Task: a0cd4477457acc81
Base: dev-v2.0.29
Head: bugfix/autodev-2218-20260805062958307
Head SHA: faeead8ffae2d753bac7f79e8ce96e4a56d13474

OpenCodeReview: No comments generated. Looks good to me.

Generated by cloud-assistant via Open Code Review.

@Memtensor-AI

Copy link
Copy Markdown
Collaborator Author

🔧 Open Code Review requested Agent fix

Open Code Review found 1 issue(s). I have resumed the development Agent to fix them.

  • Task: a0cd4477457acc81
  • Fix attempt: 1/2
  • Finding delta: 0 repeated / 1 new / 0 likely resolved

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>
@Memtensor-AI

Copy link
Copy Markdown
Collaborator Author

✅ Automated Test Results: PASSED

All tests passed (69/69 executed). memos_local_plugin/changed-repo-python: 60/60, memos_python_core/changed-repo-python: 9/9. Duration: 7s

Branch: bugfix/autodev-2218-20260805062958307

@Memtensor-AI Memtensor-AI added status:ready Ready for implementation; waiting for assignee or AI dispatch | 可进入实现,等待认领或派发 and removed status:in-progress Someone or AI is working on it | 人工或 AI 正在处理 labels Aug 5, 2026
@syzsunshine219

Copy link
Copy Markdown
Collaborator

Synced this PR with the latest dev-v2.0.29 (4 target-branch commits) via merge commit ddb1984b; the merge completed without conflicts.

I independently reproduced the original regression on the target branch: a localized OSError(10061, ...) was classified as blocked. On the updated PR head it is classified as free. I found no additional defect in the PR implementation, so no functional changes beyond the target-branch sync were needed.

Local verification on ddb1984b:

  • focused regression/viewer/cache suite: 17/17 passed
  • all local-plugin Python unittest tests: 114/114 passed
  • pytest test_bridge_client.py: 60/60 passed
  • Ruff check and format check on both changed files: passed
  • git diff --check: passed

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.

@Hun-ger

Hun-ger commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Closing as superseded by #2230, which is merged into main and includes the Windows connection-refused handling for errno/winerror 10061 with regression coverage.

@Hun-ger Hun-ger closed this Aug 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai:generated Generated or modified by AI | 由 AI 生成或修改 area:plugin OpenClaw & Hermes status:ready Ready for implementation; waiting for assignee or AI dispatch | 可进入实现,等待认领或派发

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants