Environment
- OpenClaw: 2026.4.2
- Plugin: @memtensor/memos-local-openclaw-plugin (installed via install.sh)
- OS: macOS 26.3.1 (arm64)
- Node: 22.18.0
Problem
Every time the gateway starts, the plugin's self-starting viewer fires twice (or more), creating duplicate Viewer instances on consecutive ports (18799, 18800, 18801...).
Each restart adds more instances because the previous ones are not cleaned up — ports keep accumulating.
Log output
[plugins] memos-local: service.start() not called by host, self-starting viewer...
[plugins] memos-local: started (embedding: openai_compatible)
[plugins] ║ → http://127.0.0.1:18799 ║
[plugins] memos-local: service.start() not called by host, self-starting viewer...
[plugins] Viewer port 18799 in use, trying 18800
[plugins] memos-local: started (embedding: openai_compatible)
[plugins] ║ → http://127.0.0.1:18800 ║
Root cause
OpenClaw gateway loads the plugin multiple times (once per session/agent). The serviceStarted guard in index.ts is a local variable scoped to each plugin load, so it resets to false every time. The setTimeout fallback then triggers startServiceCore() independently in each load.
Expected behavior
The Viewer should start exactly once, regardless of how many times the gateway loads the plugin.
Suggested fix
Use a cross-instance guard, e.g.:
const g = globalThis as any;
if (g.__memos_local_viewer_started__) return;
g.__memos_local_viewer_started__ = true;
Or use a file lock / port check before attempting to start.
Environment
Problem
Every time the gateway starts, the plugin's
self-starting viewerfires twice (or more), creating duplicate Viewer instances on consecutive ports (18799, 18800, 18801...).Each restart adds more instances because the previous ones are not cleaned up — ports keep accumulating.
Log output
Root cause
OpenClaw gateway loads the plugin multiple times (once per session/agent). The
serviceStartedguard inindex.tsis a local variable scoped to each plugin load, so it resets tofalseevery time. ThesetTimeoutfallback then triggersstartServiceCore()independently in each load.Expected behavior
The Viewer should start exactly once, regardless of how many times the gateway loads the plugin.
Suggested fix
Use a cross-instance guard, e.g.:
Or use a file lock / port check before attempting to start.