-
-
Notifications
You must be signed in to change notification settings - Fork 79.1k
Skill registry: changes to skills.load.extraDirs do not propagate to existing per-session skillsSnapshot #83782
Copy link
Copy link
Closed
Labels
P2Normal backlog priority with limited blast radius.Normal backlog priority with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.ClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.ClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.Session, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Metadata
Metadata
Assignees
Labels
P2Normal backlog priority with limited blast radius.Normal backlog priority with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.ClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.ClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.ClawSweeper found a high-confidence source-level issue reproduction.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.Session, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.Very strong issue quality with high-confidence source-level or clear reproduction.
Type
Fields
Give feedbackNo fields configured for issues without a type.
Summary
Adding a new root to
skills.load.extraDirsin~/.openclaw/openclaw.jsonmakes the skill visible in
openclaw skills list --agent <agent>but itnever reaches the per-session
--plugin-dirmount that gets passed toclaude. Existing sessions keep using their cachedskillsSnapshotandnever pick the new extraDirs roots up. Restarting Gateway / opening a fresh
session is required as a workaround.
Version
openclaw@2026.5.7(npm-managed install).Reproduce
skills.load.extraDirs, e.g."skills": { "load": { "extraDirs": ["/some/shared/skills"] } }SKILL.mdunder/some/shared/skills/example-skill/.openclaw skills list --agent <agent> --jsonshows the skill with
source: "openclaw-extra".ls /tmp/openclaw/openclaw-claude-skills-*/openclaw-skills/skills/The new skill is NOT present, even though plugin-generated extras with
the same
source: "openclaw-extra"label (e.g.browser-automation)ARE present.
Root cause
dist/refresh-*.js :: ensureSkillsWatcher(...)rebuilds its chokidarwatcher when
watchTargetschange (set of paths derived from extraDirs +plugin skill dirs), but it does NOT call
bumpSkillsSnapshotVersion(...)in that branch. The per-session reuse gate at
dist/session-updates-*.js :: shouldRefreshSnapshotForVersion(...)onlycompares snapshot versions, so existing sessions keep their stale
skillsSnapshot. SubsequentprepareClaudeCliSkillsPlugin(...)onlymaterializes skills present in that stale snapshot.
(File suffixes elided since they are per-release content hashes.)
Proposed fix
When
ensureSkillsWatcherdetects thatpathsKey(the joined watchtargets) has changed vs the previous watcher, bump the snapshot version
once, with
reason: "watch-targets". Minimal diff (logical, againstdist/refresh-*.js :: ensureSkillsWatcher):const watchTargets = resolveWatchTargets(workspaceDir, params.config); const pathsKey = watchTargets.join("|"); + const watchTargetsChanged = Boolean(existing) && existing.pathsKey !== pathsKey; if (existing && existing.pathsKey === pathsKey && existing.debounceMs === debounceMs) return; ... watchers.set(workspaceDir, state); + if (watchTargetsChanged) { + bumpSkillsSnapshotVersion({ + workspaceDir, + reason: "watch-targets", + changedPath: pathsKey, + }); + } }This is the narrowest fix: it doesn't broaden which sources may mount, it
only invalidates stale per-session snapshots when the set of watched skill
roots changes. SKILL.md file changes already bump via the existing watcher
events; this adds the missing equivalent for root-set changes from config
or plugin-skill path changes.
Workaround
Manually trigger a fresh session after editing
extraDirs, or restartGateway, so the new sessions rebuild
skillsSnapshotfrom scratch.