Skip to content

fix[Bug]: [skills] Skipping skill path error triggered on officially installed skills via clawhub (WSL Environment)#44082

Closed
luoxiao6645 wants to merge 0 commit intoopenclaw:mainfrom
luoxiao6645:fix/44051-managed-skills-realpath-scope
Closed

fix[Bug]: [skills] Skipping skill path error triggered on officially installed skills via clawhub (WSL Environment)#44082
luoxiao6645 wants to merge 0 commit intoopenclaw:mainfrom
luoxiao6645:fix/44051-managed-skills-realpath-scope

Conversation

@luoxiao6645
Copy link
Copy Markdown

@luoxiao6645 luoxiao6645 commented Mar 12, 2026

fix[Bug]: [skills] Skipping skill path error triggered on officially installed skills via clawhub (WSL Environment) #44051

Summary

Fix a managed skills loading regression introduced by the skills realpath boundary hardening.

In 2026.3.9, the loader started rejecting skill roots and SKILL.md files whose
resolved realpath escaped the configured source root. That behavior is correct for
workspace and extra-dir skills, but it was also being applied to managed skills under
~/.openclaw/skills.

As a result, managed skills installed via symlink/junction-backed layouts could be
skipped with:

Skipping skill path that resolves outside its configured root.

This was surfacing in WSL reports, but the bug is in source scoping rather than
WSL-specific path normalization.

Root Cause

The containment check in src/agents/skills/workspace.ts was enforced for all skill
sources, including openclaw-managed.

That meant a skill path that appeared under ~/.openclaw/skills/<name> but resolved
outside that directory via realpath was rejected, even though managed skill roots are
user-owned shared roots and were not intended to be subject to the workspace/extra-dir
escape restriction.

What Changed

  • Added shouldEnforceContainedSkillPaths() to scope realpath boundary enforcement to:
    • openclaw-workspace
    • openclaw-extra
    • agents-skills-project
  • Stopped applying that enforcement to managed/personal/bundled roots.
  • Kept size checks and normal loading behavior unchanged for trusted shared roots.
  • Added regression coverage for symlinked managed skills.
  • Kept workspace escape coverage in place to ensure untrusted workspace roots still fail closed.

Files

  • src/agents/skills/workspace.ts
  • src/agents/skills.loadworkspaceskillentries.test.ts

Test

full test
Passed:

  • pnpm exec vitest run src/agents/skills.loadworkspaceskillentries.test.ts
  • pnpm exec vitest run src/agents/skills.buildworkspaceskillsnapshot.test.ts
  • pnpm exec vitest run src/agents/skills.build-workspace-skills-prompt.syncs-merged-skills-into-target-workspace.test.ts
  • pnpm exec vitest run src/agents/skills.build-workspace-skills-prompt.prefers-workspace-skills-managed-skills.test.ts
  • pnpm exec vitest run src/agents/skills-status.test.ts
    AI assisted by Codex 5.4

@openclaw-barnacle openclaw-barnacle bot added agents Agent runtime and tooling size: S labels Mar 12, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 12, 2026

Greptile Summary

This PR fixes a regression introduced in 2026.3.9 where the realpath containment check (intended to prevent workspace symlink-escape attacks) was incorrectly applied to all skill sources, including user-trusted managed, bundled, and personal-agents roots. The fix adds shouldEnforceContainedSkillPaths() to scope enforcement to only the three untrusted/repo-scoped sources (openclaw-workspace, openclaw-extra, agents-skills-project), while leaving managed/bundled/personal roots free to follow symlinks — which is required for legitimate symlink- or junction-backed installations from clawhub (and is the correct behavior in WSL cross-filesystem layouts).

Key changes:

  • shouldEnforceContainedSkillPaths() cleanly centralises the source-type decision; all downstream callers (resolveContainedSkillPath, filterLoadedSkillsInsideRoot) are correctly conditioned on it.
  • Size cap enforcement (fs.statSync) still applies to all sources regardless of containment enforcement, preserving the protection against oversized SKILL.md files.
  • The non-enforcement fallback for baseDirRealPath (tryRealpath(baseDir) ?? path.resolve(baseDir)) correctly avoids a spurious early-return for trusted roots that happen to sit behind a broken-realpath directory entry.
  • A symlinkDir helper is extracted in tests to make symlink creation cross-platform (Windows junction vs. Unix dir), and the previously Windows-skipped workspace-escape test is promoted to run on all platforms via that helper.
  • A new regression test confirms that managed skills symlinked outside the managed root are now loaded, while the workspace-escape rejection test is preserved.

Confidence Score: 5/5

  • This PR is safe to merge; it is a targeted, well-tested regression fix with no risky side-effects.
  • The change is narrowly scoped — a single predicate function gates the containment check, all pre-existing security paths for workspace/extra/project sources remain fully enforced, and size-cap checks apply universally. New and existing tests cover both the fixed behaviour (managed symlinks allowed) and the preserved security invariant (workspace escape still rejected). No unrelated code is touched.
  • No files require special attention.

Last reviewed commit: a8662f2

@luoxiao6645 luoxiao6645 force-pushed the fix/44051-managed-skills-realpath-scope branch from f6dde2c to f8c8845 Compare March 13, 2026 11:46
@openclaw-barnacle openclaw-barnacle bot added the channel: whatsapp-web Channel integration: whatsapp-web label Mar 15, 2026
@openclaw-barnacle openclaw-barnacle bot added channel: discord Channel integration: discord channel: matrix Channel integration: matrix channel: whatsapp-web Channel integration: whatsapp-web size: M and removed channel: whatsapp-web Channel integration: whatsapp-web size: S labels Mar 18, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2ffdef4577

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@openclaw-barnacle openclaw-barnacle bot added size: L size: M channel: discord Channel integration: discord and removed size: M channel: discord Channel integration: discord size: L labels Mar 19, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b654b94164

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7b64a725ba

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 374f380515

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ae1c0292d1

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 30699efe9a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@luoxiao6645 luoxiao6645 force-pushed the fix/44051-managed-skills-realpath-scope branch from 75e6f9d to 3d8eccc Compare March 20, 2026 12:50
@openclaw-barnacle openclaw-barnacle bot removed channel: discord Channel integration: discord channel: matrix Channel integration: matrix labels Mar 20, 2026
@openclaw-barnacle openclaw-barnacle bot added size: M and removed channel: whatsapp-web Channel integration: whatsapp-web size: L labels Mar 20, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4efda6501a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@luoxiao6645 luoxiao6645 force-pushed the fix/44051-managed-skills-realpath-scope branch from 4efda65 to a21b989 Compare March 21, 2026 10:45
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5db9a3ee72

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@luoxiao6645 luoxiao6645 force-pushed the fix/44051-managed-skills-realpath-scope branch from 5db9a3e to a21b989 Compare March 21, 2026 11:58
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c1c625ed2e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@luoxiao6645 luoxiao6645 force-pushed the fix/44051-managed-skills-realpath-scope branch from 9290d28 to a21b989 Compare March 21, 2026 12:48
@luoxiao6645
Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Swish!

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@luoxiao6645 luoxiao6645 force-pushed the fix/44051-managed-skills-realpath-scope branch from c3a9894 to a21b989 Compare March 21, 2026 13:10
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8514f560f2

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7a5cd180a7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

"tavily",
"xai",
] as const;
import { bundledWebSearchPluginRegistrations } from "../bundled-web-search-registry.js";
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Decouple web-search ID lookup from eager plugin imports

Importing bundled-web-search-registry here eagerly loads all bundled web-search plugin modules via that registry’s top-level imports, so listBundledWebSearchPluginIds() now fails at module load time if any single bundled plugin module is unavailable (for example in stripped or partially built environments). This can break callers such as config validation before compat logic runs, and the local try/catch around entry.plugin.id cannot intercept those failures because they occur before the function executes.

Useful? React with 👍 / 👎.

@luoxiao6645 luoxiao6645 force-pushed the fix/44051-managed-skills-realpath-scope branch from d9790c6 to c93c0d5 Compare March 22, 2026 10:35
@openclaw-barnacle openclaw-barnacle bot added size: XS and removed agents Agent runtime and tooling size: M labels Mar 22, 2026
@luoxiao6645 luoxiao6645 force-pushed the fix/44051-managed-skills-realpath-scope branch from c93c0d5 to 67e61ac Compare March 22, 2026 10:37
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c93c0d5bfe

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

"tavily",
"xai",
] as const;
import { bundledWebSearchPluginRegistrations } from "../bundled-web-search-registry.js";
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep ID fast path independent of bundled plugin module loads

Importing bundled-web-search-registry at module scope makes listBundledWebSearchPluginIds() eagerly load every bundled web-search plugin before the function body runs, so the local try/catch cannot handle import-time failures. In environments where a bundled web-search plugin is unavailable (for example, a partial/stripped build), callers that only need compat IDs (such as config validation via src/config/validation.ts) will now fail during module initialization instead of degrading gracefully.

Useful? React with 👍 / 👎.

@luoxiao6645
Copy link
Copy Markdown
Author

luoxiao6645 commented Mar 22, 2026

Closed in favor of #52202 to keep the conversation and commits clean.
#52202

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant