Skip to content

memos-local-openclaw-plugin@1.0.8 self-start viewer repeats under host lifecycle mismatch, causing port drift (18799→18800+), Memory unavailable #1430

@TelDragon

Description

@TelDragon

Pre-submission checklist | 提交前检查

  • I have searched existing issues and this hasn't been mentioned before | 我已搜索现有问题,确认此问题尚未被提及
  • I have read the project documentation and confirmed this issue doesn't already exist | 我已阅读项目文档并确认此问题尚未存在
  • This issue is specific to MemOS and not a general software issue | 该问题是针对 MemOS 的,而不是一般软件问题

Bug Description | 问题描述

Environment
OpenClaw: 2026.4.5
Plugin: @memtensor/memos-local-openclaw-plugin@1.0.8
OS: Windows 11
Node: 24.14.0
Config:
plugins.entries.memos-local-openclaw-plugin.config.viewerPort = 18799
Current behavior
Even with viewerPort fixed to 18799, Memory still becomes unavailable in status checks.

Observed logs repeatedly show:

memos-local: service.start() not called by host, self-starting viewer...
then port fallback:
Viewer port 18799 in use, trying 18800
Viewer port 18800 in use, trying 18801
...
openclaw status --deep often reports:

Memory: enabled (plugin memos-local-openclaw-plugin) · unavailable
Reproduction (minimal)
Install/update plugin to 1.0.8
Set fixed port:
Restart gateway
Run openclaw status --deep / openclaw plugins inspect ... multiple times
Observe self-start logs and viewer moving to 18800+, while Memory may stay unavailable
Expected behavior
If viewerPort=18799, plugin should either:
use exactly that port and fail clearly if occupied, or
keep health as available when core memory service is healthy.
Repeated plugin register/init in same process should not trigger repeated self-start attempts.
status --deep should not degrade Memory health due to duplicate self-start side effects.
Actual behavior
service.start() is not always called by host path.
Plugin fallback self-starting viewer... is triggered repeatedly.
Viewer fallback consumes next ports (18800+).
Memory health may show unavailable despite plugin DB/embedding being initialized.
Root-cause hypothesis
Lifecycle mismatch: plugin registerService occurs, but service.start is not guaranteed on all load paths.
Fallback self-start is not globally idempotent across repeated register/init cycles.
Health status likely coupled too tightly to viewer startup result.
Local workaround/patch used
I added a process-level singleton guard in index.ts to make startup idempotent per (pid,stateDir,viewerPort):

guard state on globalThis:
starting
started
skip duplicate starts when already starting/started
reset guard on stop()
This reduced repeated same-process viewer starts and stabilized fixed port behavior.

Patch idea (pseudo)
Copy
const globalState = globalThis as Record<string, any>;
const root = "memos_local_start_guard";
if (!globalState[root]) globalState[root] = {};
const key = ${process.pid}:${stateDir}:${viewerPort};
const singleton = (globalState[root][key] ||= { starting: false, started: false });

if (singleton.started) return;
if (singleton.starting) return;
singleton.starting = true;
try {
await viewer.start();
singleton.started = true;
} finally {
singleton.starting = false;
}
Suggested upstream fix
Make service startup idempotent at plugin level across repeated register/init.
Revisit host lifecycle integration to avoid “registered but start hook not fired” path.
Decouple Memory health from viewer port fallback side-effects (or treat viewer as optional health dimension).
If viewerPort is explicitly configured, consider strict mode (no auto-drift) + explicit warning.
Extra notes
This is not a ClawHub rate-limit issue (already bypassed with npm install/update).
Not primarily embedding failure either; logs show embedding can initialize while health still unavailable.

How to Reproduce | 如何重现

1

Environment | 环境信息

1

Additional Context | 其他信息

1

Willingness to Implement | 实现意愿

  • I'm willing to implement this myself | 我愿意自己解决
  • I would like someone else to implement this | 我希望其他人来解决

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpendingPending items to be addressed | 待解决事项。

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions