openclaw - ✅(Solved) Fix Bug: stale skillsSnapshot can hide newly added skills after restart [2 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#69715Fetched 2026-04-22 07:49:05
View on GitHub
Comments
0
Participants
1
Timeline
2
Reactions
0
Participants
Timeline (top)
cross-referenced ×2

Persisted sessions can keep using a stale skillsSnapshot and miss newly added skills after a gateway restart.

I hit this on April 21, 2026 in a Feishu DM session. A new local skill existed on disk and was eligible, but the session kept behaving as if the skill did not exist until the session was reset/refreshed.

Root Cause

There are two pieces that combine badly:

  1. shouldRefreshSnapshotForVersion() returns false when both the cached version and the current version are 0.
  2. ensureSkillSnapshot() reads snapshotVersion before calling ensureSkillsWatcher().

That means an old persisted session snapshot with version = 0 can compare equal to the fresh process state, and the next turn does not rebuild the snapshot.

Fix Action

Fixed

PR fix notes

PR #69716: fix(skills): refresh stale session skill snapshots after restart

Description (problem / solution / changelog)

Summary

Fixes a stale-session edge case where newly added skills can stay invisible after a gateway restart.

Fixes #69715.

What Changed

  • seed a non-zero skills snapshot version when the first workspace watcher is attached
  • read snapshotVersion after ensureSkillsWatcher() in ensureSkillSnapshot()
  • add regression coverage for both behaviors

Why

A persisted session snapshot with version = 0 could compare equal to the fresh process state after restart, so the next turn would skip rebuilding the snapshot. In practice that let existing sessions miss newly added workspace skills until the session was reset or otherwise refreshed.

Testing

  • git diff --check
  • Added focused unit tests in:
    • src/agents/skills/refresh.test.ts
    • src/auto-reply/reply/session-updates.test.ts
  • Not run locally: this checkout does not have node_modules, vitest, or pnpm installed, so node scripts/run-vitest.mjs ... fails with Cannot find module 'vitest/package.json'.

Changed files

  • src/agents/skills/refresh.test.ts (modified, +8/-0)
  • src/agents/skills/refresh.ts (modified, +9/-0)
  • src/auto-reply/reply/session-updates.test.ts (modified, +24/-0)
  • src/auto-reply/reply/session-updates.ts (modified, +1/-1)

PR #69734: fix(skills): refresh stale session snapshots after gateway restart

Description (problem / solution / changelog)

Fixes #69715

Persisted sessions with a skillsSnapshot.version of 0 would not refresh after a gateway restart because:

  1. ensureSkillSnapshot() called getSkillsSnapshotVersion() before ensureSkillsWatcher(), so the version was still 0.
  2. shouldRefreshSnapshotForVersion(0, 0) returns false, so the stale snapshot was reused.

This meant newly added skills were invisible to existing sessions until a watcher event bumped the version.

Fix (two parts):

  1. In ensureSkillSnapshot(): move getSkillsSnapshotVersion() to after ensureSkillsWatcher() so the watcher has a chance to seed a version first.

  2. In ensureSkillsWatcher(): seed a non-zero workspace version when a new watcher is attached, so the first post-restart turn in an existing session observes a changed version and rebuilds the snapshot.

Both changes are backward-compatible and only affect the first turn after a gateway restart for sessions that had a version-0 snapshot.

Changed files

  • src/agents/skills/refresh.ts (modified, +4/-0)
  • src/auto-reply/reply/session-updates.ts (modified, +1/-1)
RAW_BUFFERClick to expand / collapse

Summary

Persisted sessions can keep using a stale skillsSnapshot and miss newly added skills after a gateway restart.

I hit this on April 21, 2026 in a Feishu DM session. A new local skill existed on disk and was eligible, but the session kept behaving as if the skill did not exist until the session was reset/refreshed.

Repro

  1. Start a long-lived session so it persists a skillsSnapshot with version = 0.
  2. Add a new skill to the workspace after that session already exists.
  3. Restart the gateway before a watcher event bumps the workspace skill snapshot version.
  4. Send the next message in the existing session.

Actual

The existing session can keep reusing the old snapshot and fail to surface the newly added skill.

In my case the session could not see a newly added mock-full-reduction-config skill from the available_skills list, even though the skill was present on disk and openclaw skills check reported it as ready.

Expected

The first post-restart turn in an existing session should rebuild the skills snapshot if the process has not yet established a non-zero workspace version.

Root Cause

There are two pieces that combine badly:

  1. shouldRefreshSnapshotForVersion() returns false when both the cached version and the current version are 0.
  2. ensureSkillSnapshot() reads snapshotVersion before calling ensureSkillsWatcher().

That means an old persisted session snapshot with version = 0 can compare equal to the fresh process state, and the next turn does not rebuild the snapshot.

Proposed Fix

  • Seed a non-zero workspace snapshot version when the first watcher for a workspace is attached.
  • In ensureSkillSnapshot(), call ensureSkillsWatcher() before reading getSkillsSnapshotVersion(workspaceDir).

That makes the first post-restart turn observe the bumped version and refresh stale session snapshots.

Notes

I also added focused regression tests locally for both behaviors:

  • watcher attachment seeds a non-zero version
  • ensureSkillSnapshot() reads the version after ensuring the watcher

extent analysis

TL;DR

The issue can be resolved by modifying the ensureSkillSnapshot() function to call ensureSkillsWatcher() before reading the snapshot version and seeding a non-zero workspace snapshot version when the first watcher is attached.

Guidance

  • Review the shouldRefreshSnapshotForVersion() function to ensure it correctly handles cases where both the cached and current versions are 0.
  • Modify the ensureSkillSnapshot() function to call ensureSkillsWatcher() before reading getSkillsSnapshotVersion(workspaceDir) to ensure the snapshot version is updated before comparison.
  • Seed a non-zero workspace snapshot version when the first watcher for a workspace is attached to prevent stale session snapshots.
  • Verify the fix by testing the scenario described in the repro steps and checking if the session correctly rebuilds the skills snapshot after a gateway restart.

Example

def ensureSkillSnapshot(workspaceDir):
    ensureSkillsWatcher()  # Call ensureSkillsWatcher before reading snapshot version
    snapshotVersion = getSkillsSnapshotVersion(workspaceDir)
    # ... rest of the function remains the same

Notes

The proposed fix assumes that the ensureSkillsWatcher() function correctly updates the snapshot version. Additional testing may be necessary to ensure the fix works as expected in all scenarios.

Recommendation

Apply the proposed workaround by modifying the ensureSkillSnapshot() function and seeding a non-zero workspace snapshot version when the first watcher is attached, as this directly addresses the identified root cause of the issue.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix Bug: stale skillsSnapshot can hide newly added skills after restart [2 pull requests, 1 participants]