Bug: Skills snapshot not refreshed for existing sessions after gateway restart
Summary
When new skills are installed while the gateway is running, existing sessions continue using a stale skill snapshot even after gateway restart. Only new sessions (created after skill installation) see the updated skill list. This is caused by two interacting issues in the snapshot version system.
Steps to Reproduce
- Start the gateway with N skills installed
- Create a session (e.g., Discord channel) — session captures snapshot with N skills
- Install a new skill (e.g.,
clawhub install <skill>) — watcher bumps workspaceVersions
- Restart the gateway
- Send a message in the existing session
- Observe: session still shows N skills, not N+1
- Create a new session (
/new or new channel) — shows N+1 skills ✅
Root Cause
There are two code paths for skill snapshot refresh, both affected:
Path A — manager.runtime-CXnMXwZT.js (general channels)
const needsSkillsSnapshot = isNewSession || !sessionEntry?.skillsSnapshot;
const skillsSnapshotVersion = getSkillsSnapshotVersion(workspaceDir);
const skillsSnapshot = needsSkillsSnapshot
? buildWorkspaceSkillSnapshot(workspaceDir, { snapshotVersion, ... })
: sessionEntry?.skillsSnapshot; // ← reuses old snapshot, no version check
Problem: No version comparison at all. If sessionEntry.skillsSnapshot exists, it's always reused regardless of whether the skill list has changed.
Path B — discord-CcCLMjHw.js (Discord-specific, ensureSkillSnapshot)
const snapshotVersion = getSkillsSnapshotVersion(workspaceDir);
ensureSkillsWatcher({ workspaceDir, config: cfg });
const shouldRefreshSnapshot = snapshotVersion > 0
&& (nextEntry?.skillsSnapshot?.version ?? 0) < snapshotVersion;
Problem: globalVersion (module-level variable) resets to 0 on process start:
// model-selection-46xMp11W.js
let globalVersion = 0; // ← reset every restart
function getSkillsSnapshotVersion(workspaceDir) {
const local = workspaceVersions.get(workspaceDir) ?? 0;
return Math.max(globalVersion, local); // ← returns 0 after restart
}
After restart: getSkillsSnapshotVersion() returns 0 → snapshotVersion > 0 is false → shouldRefreshSnapshot is always false.
The file watcher (ensureSkillsWatcher) would bump the version on file changes, but:
- It uses
ignoreInitial: true (correct — avoids false triggers on startup)
- If the skill was installed before restart, the watcher won't detect a change
- So
globalVersion stays 0, and the snapshot is never refreshed
Impact
- Any user who installs a new skill and restarts the gateway will find their existing sessions don't see the new skills
- The workaround is to manually delete
skillsSnapshot from all sessions in sessions.json, or use /new//reset on each session
- With many sessions (e.g., 58 in our setup), this is impractical
Additional Issues
-
Two code paths with different behavior: Path A completely ignores versions, Path B tries but fails due to globalVersion = 0. All channels should follow the same refresh logic.
-
Per-session snapshot duplication: Each session stores its own copy of skillsSnapshot (~11.5KB). With N sessions, this is N × 11.5KB of identical data. This should be a shared reference per agent.
-
No startup diff check: The system has no mechanism to compare the current skill list against stored snapshots at startup. A simple hash comparison on startup would catch staleness.
Proposed Fixes
- Persist
globalVersion — Write it to sessions.json or a separate file so it survives restarts
- Add startup diff check — On gateway start, compute a hash of the current skill list. If it differs from any session's snapshot, bump the version
- Unify code paths — Path A should also check version, not just
isNewSession || !snapshot
- Remove the
snapshotVersion > 0 guard — Or at least handle the cold-start case where version is 0 but snapshot may be stale
- Store snapshot per-agent, not per-session — Share a single snapshot reference across all sessions for the same agent
Version
OpenClaw 2026.3.13 (also present in 2026.3.8, likely earlier)
Environment
- macOS (arm64)
- Node.js v25.8.1
- Discord channel integration
- Skills installed via
clawhub install
Bug: Skills snapshot not refreshed for existing sessions after gateway restart
Summary
When new skills are installed while the gateway is running, existing sessions continue using a stale skill snapshot even after gateway restart. Only new sessions (created after skill installation) see the updated skill list. This is caused by two interacting issues in the snapshot version system.
Steps to Reproduce
clawhub install <skill>) — watcher bumpsworkspaceVersions/newor new channel) — shows N+1 skills ✅Root Cause
There are two code paths for skill snapshot refresh, both affected:
Path A —
manager.runtime-CXnMXwZT.js(general channels)Problem: No version comparison at all. If
sessionEntry.skillsSnapshotexists, it's always reused regardless of whether the skill list has changed.Path B —
discord-CcCLMjHw.js(Discord-specific,ensureSkillSnapshot)Problem:
globalVersion(module-level variable) resets to 0 on process start:After restart:
getSkillsSnapshotVersion()returns 0 →snapshotVersion > 0is false →shouldRefreshSnapshotis always false.The file watcher (
ensureSkillsWatcher) would bump the version on file changes, but:ignoreInitial: true(correct — avoids false triggers on startup)globalVersionstays 0, and the snapshot is never refreshedImpact
skillsSnapshotfrom all sessions insessions.json, or use/new//reseton each sessionAdditional Issues
Two code paths with different behavior: Path A completely ignores versions, Path B tries but fails due to
globalVersion = 0. All channels should follow the same refresh logic.Per-session snapshot duplication: Each session stores its own copy of
skillsSnapshot(~11.5KB). With N sessions, this is N × 11.5KB of identical data. This should be a shared reference per agent.No startup diff check: The system has no mechanism to compare the current skill list against stored snapshots at startup. A simple hash comparison on startup would catch staleness.
Proposed Fixes
globalVersion— Write it tosessions.jsonor a separate file so it survives restartsisNewSession || !snapshotsnapshotVersion > 0guard — Or at least handle the cold-start case where version is 0 but snapshot may be staleVersion
OpenClaw 2026.3.13 (also present in 2026.3.8, likely earlier)
Environment
clawhub install