openclaw - ✅(Solved) Fix [Bug]: Invalid skill slug: spclaudehome/skill-vetter [1 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#71767Fetched 2026-04-26 05:08:40
View on GitHub
Comments
0
Participants
1
Timeline
4
Reactions
0
Author
Participants
Timeline (top)
labeled ×2cross-referenced ×1referenced ×1

When I use "openclaw skills install spclaudehome/skill-vetter" to install skill-vetter, it outputs "Invalid skill slug: spclaudehome/skill-vetter"

Root Cause

When I use "openclaw skills install spclaudehome/skill-vetter" to install skill-vetter, it outputs "Invalid skill slug: spclaudehome/skill-vetter"

Fix Action

Fixed

PR fix notes

PR #71857: fix(skills): accept owner-prefixed clawhub slugs (#71767)

Description (problem / solution / changelog)

Summary

  • Problem: openclaw skills install spclaudehome/skill-vetter failed with Invalid skill slug: spclaudehome/skill-vetter even though clawhub.ai itself prints that exact command on every skill page.
  • Why it matters: Users copy-paste the install snippet shown on clawhub.ai/<owner>/<slug>, hit a hard error, and have no signal that they should drop the owner prefix. The published documentation and the CLI disagreed.
  • What changed: New local parser parseClawHubSkillSlug(raw, mode) accepts an optional <owner>/<name> prefix, validates both segments under the existing ASCII guard, and returns the canonical bare slug for the registry call, install dir, and lockfile key. normalizeTrackedSlug / validateRequestedSlug are thin wrappers; call sites unchanged.
  • What did NOT change (scope boundary): No changes to src/infra/clawhub.ts registry I/O, src/cli/skills-cli.ts, the gateway skills.install / skills.update RPCs, the plugin install path, or src/infra/install-safe-path.ts. Path-traversal protection is unchanged (safeDirName still neutralizes / and \ at the FS layer). Homograph rejection from #53206 is preserved per-segment.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #71767
  • Related #53206 (introduced the ASCII tightening; this PR keeps that guard intact while widening accepted shape)
  • Related #56779 (already added safeDirName for slash-containing slugs at the archive layer; this PR completes that direction at the validator)
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: normalizeTrackedSlug in src/agents/skills-clawhub.ts:70 rejected any input containing / as a path-traversal guard. Meanwhile, clawhub.ai renders its install snippet as openclaw skills install ${ownerHandle}/${slug} (verified in the live JS bundle: function Bq(e,t,n){let r=e?.trim();return r?`${r}/${n}`:t?`${String(t)}/${n}`:n}). The CLI was the only piece in the chain that didn't understand the form clawhub.ai itself publishes, so the documented copy-paste install never worked for any owned skill.
  • Missing detection / guardrail: No test in src/agents/skills-clawhub.test.ts exercised slugs with a / in them. PR #53206's "backward compatible? Yes — slugs that were valid before remain valid" claim was technically true for single-segment slugs, but missed that the website was already shipping owner-prefixed install commands.
  • Contributing context (if known): The original slug.includes("/") rejection landed in the very first commit of this file (91b2800241) as a path-traversal guard. PR #56779 later added safeDirName at the archive layer (src/infra/install-safe-path.ts:28), making the validator's /-rejection redundant for safety. The validator never got the memo.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/agents/skills-clawhub.test.ts
  • Scenario the test should lock in: installSkillFromClawHub({ slug: "spclaudehome/skill-vetter" }) returns { ok: true } and the downstream fetchClawHubSkillDetail / downloadClawHubSkillArchive calls receive slug: "skill-vetter". updateSkillsFromClawHub against a workspace that tracks the bare skill-vetter resolves the owner-prefixed input to the same lockfile entry. All malformed forms (a/b/c, /x, x/, a\\b, a/../b, non-ASCII per segment, hyphen edges) still return { ok: false, error: containing "Invalid skill slug" } without touching the network.
  • Why this is the smallest reliable guardrail: All slug entry points (CLI install, CLI update, gateway skills.install/skills.update) converge through installSkillFromClawHub / updateSkillsFromClawHub and the two normalizers. Asserting at that boundary covers every caller without integration tests.
  • Existing test that already covers this (if any): None. The existing 9 cases at skills-clawhub.test.ts:224-329 only exercised single-segment slugs.
  • If no new test is added, why not: 12 new test cases added (one acceptance + one mixed-case + nine rejection + one cross-form lockfile lookup).

User-visible / Behavior Changes

  • openclaw skills install <owner>/<slug> and openclaw skills update <owner>/<slug> are now accepted and behave identically to the bare-slug form — the owner prefix is informational and stripped before any further processing.
  • The lockfile and the skill install directory are still keyed by the bare slug, so installing via either form (and updating from either form) targets the same entry. Inputs without a / are unchanged.

Diagram (if applicable)

Before:
"openclaw skills install spclaudehome/skill-vetter"
  -> validateRequestedSlug
  -> normalizeTrackedSlug rejects on slug.includes("/")
  -> Error: "Invalid skill slug: spclaudehome/skill-vetter"

After:
"openclaw skills install spclaudehome/skill-vetter"
  -> validateRequestedSlug
  -> parseClawHubSkillSlug(raw, "requested")
       split "/" -> ["spclaudehome", "skill-vetter"]
       each segment passes ASCII + VALID_SLUG_PATTERN
  -> "skill-vetter"
  -> fetchClawHubSkillDetail({ slug: "skill-vetter" })  // /api/v1/skills/skill-vetter -> 200
  -> install at <workspace>/skills/skill-vetter, lock.skills["skill-vetter"]

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No (the bare slug is what the registry already expected; the owner prefix is stripped before any request)
  • Command/tool execution surface changed? No
  • Data access scope changed? No
  • If any Yes, explain risk + mitigation: N/A. Homograph protection from #53206 is preserved by applying NON_ASCII_PATTERN and VALID_SLUG_PATTERN to both segments in requested mode; path-traversal protection is preserved by rejecting \\, .., empty segments, and >1 separator before the registry/filesystem layers.

Repro + Verification

Environment

  • OS: Linux 6.8 (Ubuntu 22.04 in the issue; reproduced locally on Debian-derived host)
  • Runtime/container: Node 22.22.1, pnpm 10.33.0
  • Model/provider: N/A
  • Integration/channel (if any): N/A
  • Relevant config (redacted): default — no ClawHub credentials needed to reproduce or verify

Steps

  1. pnpm install
  2. Reproduce on main (pre-fix): pnpm test src/agents/skills-clawhub.test.ts -- --testNamePattern="owner-prefixed" → fails (3 critical assertions).
  3. Apply this branch and re-run: pnpm test src/agents/skills-clawhub.test.ts → 27/27 pass (15 baseline + 12 new).
  4. Smart gate: pnpm check:changed → conflict-markers ✓, typecheck core ✓, typecheck core tests ✓, lint core ✓, all guards ✓, 4542 tests ✓.

Expected

  • Owner-prefixed slug installs end-to-end and the registry call uses the bare slug.
  • Bare slug behavior is unchanged.
  • Malformed forms (multiple slashes, empty segments, backslash, traversal, non-ASCII per segment, hyphen edges) still error out before any network call.

Actual

  • Matches expected on all three rows.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Regression proof — running the new tests against unfixed source produced exactly the failures predicted by the analysis:

FAIL  src/agents/skills-clawhub.test.ts > owner-prefixed slugs match clawhub.ai install snippets > strips the owner prefix and installs the bare slug
  AssertionError: expected "vi.fn()" to be called with arguments: [ { slug: 'skill-vetter', baseUrl: undefined } ]
  Number of calls: 0

FAIL  > accepts mixed-case owner-prefixed slugs
  AssertionError: expected "vi.fn()" to be called with arguments: [ { slug: 'Skill-Vetter', ...

FAIL  > updates a bare-slug install when invoked with the owner-prefixed form
  Error: Invalid skill slug: spclaudehome/skill-vetter
   ❯ normalizeTrackedSlug src/agents/skills-clawhub.ts:73:11
   ❯ resolveRequestedUpdateSlug src/agents/skills-clawhub.ts:91:23
   ❯ updateSkillsFromClawHub src/agents/skills-clawhub.ts:420:15

Tests  3 failed | 24 passed (27)

After the fix on the same test file: Tests 27 passed (27).

Source confirmation that clawhub.ai publishes the owner-prefixed form (extracted from the live assets/main-B2D6xuZn.js bundle):

function Bq(e, t, n) {                         // e = ownerHandle, t = ownerId, n = slug
  let r = e?.trim();
  return r ? `${r}/${n}` : t ? `${String(t)}/${n}` : n;
}
function Hq(e, t, n) {
  return `openclaw skills install ${Bq(e, t, n)}`;
}

Registry confirmation: GET /api/v1/skills/skill-vetter → 200 with slug: "skill-vetter", owner.handle: "spclaudehome". GET /api/v1/skills/spclaudehome%2Fskill-vetter → 404. Bare slug is canonical at the API; owner prefix is a UI affordance.

Human Verification (required)

  • Verified scenarios:
    • Install with owner-prefix: installSkillFromClawHub({ slug: "spclaudehome/skill-vetter" }) calls fetchClawHubSkillDetail({ slug: "skill-vetter" }) and returns ok: true with slug: "skill-vetter".
    • Update cross-form: workspace tracks skill-vetter; updateSkillsFromClawHub({ slug: "spclaudehome/skill-vetter" }) resolves to that lockfile entry and uses the saved registry URL.
    • Mixed-case owner-prefix preserved end-to-end.
    • Each rejection edge case fails fast with the existing Invalid skill slug: <raw> error, no network call.
    • Legacy non-ASCII tracked-slug update path (existing test at skills-clawhub.test.ts:160) still passes — tracked mode keeps lenient ASCII handling.
  • Edge cases checked: empty input, whitespace-only input, .. traversal, backslash, /skill, skill/, //, a/b/c, leading hyphen on either segment, trailing hyphen on either segment, Cyrillic homograph in either segment, mixed case, single-segment regression.
  • What I did not verify: gateway RPC path against a live gateway instance (the gateway forwards slug unchanged to installSkillFromClawHub, so the boundary fix covers it). I did not exercise a real network round-trip against clawhub.ai; the API contract was confirmed via direct curl to /api/v1/skills/skill-vetter only.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? Yes — slugs that were valid before remain valid. Newly-accepted owner-prefixed forms canonicalize to the same bare slug used by existing single-segment installs, so install dirs and lockfile keys never change.
  • Config/env changes? No
  • Migration needed? No
  • If yes, exact upgrade steps: N/A

Risks and Mitigations

  • Risk: A user who previously installed react (bare) and runs update someowner/react might be confused if they think someowner/react is a different skill.
    • Mitigation: Slugs are globally unique on ClawHub (registry serves a single skill per slug regardless of owner; verified at /api/v1/skills/<slug>). The owner prefix is purely informational, matching the website's own treatment.
  • Risk: Future ClawHub schema change adds owner-namespaced slugs (so owner/name and name would refer to different skills).
    • Mitigation: Localized to one helper. If the schema changes, the parser is the single place to update; lockfile/install-dir keying lives in the same file.

Changed files

  • CHANGELOG.md (modified, +5/-0)
  • src/agents/skills-clawhub.test.ts (modified, +216/-0)
  • src/agents/skills-clawhub.ts (modified, +23/-9)

Code Example

ai@win11:~$ openclaw skills install spclaudehome/skill-vetter

🦞 OpenClaw 2026.4.23 (a979721)The only crab in your contacts you actually want to hear from. 🦞

Invalid skill slug: spclaudehome/skill-vetter
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

When I use "openclaw skills install spclaudehome/skill-vetter" to install skill-vetter, it outputs "Invalid skill slug: spclaudehome/skill-vetter"

Steps to reproduce

openclaw skills install spclaudehome/skill-vetter

Expected behavior

Successfully install skill-vetter as the document(https://clawhub.ai/spclaudehome/skill-vetter) says.

Actual behavior

Invalid skill slug: spclaudehome/skill-vetter

OpenClaw version

2026.4.23

Operating system

Ubuntu 22.04

Install method

npm global

Model

openai-codex

Provider / routing chain

openclaw -> gateway -> openai-codex

Additional provider/model setup details

No response

Logs, screenshots, and evidence

ai@win11:~$ openclaw skills install spclaudehome/skill-vetter

🦞 OpenClaw 2026.4.23 (a979721) — The only crab in your contacts you actually want to hear from. 🦞

Invalid skill slug: spclaudehome/skill-vetter

Impact and severity

No response

Additional information

No response

extent analysis

TL;DR

The issue might be due to an incorrect skill slug, so checking the documentation or the ClawHub website for the correct slug is necessary.

Guidance

  • Verify the skill slug "spclaudehome/skill-vetter" is correct by checking the ClawHub website or documentation for the skill-vetter installation.
  • Ensure the OpenClaw version 2026.4.23 supports the installation of skills from the specified source.
  • Check if there are any specific installation instructions or prerequisites for the skill-vetter skill that might be missing.
  • Consider searching for similar issues or troubleshooting guides on the OpenClaw or ClawHub platforms.

Notes

The provided information does not include specific details about the skill-vetter skill or its installation requirements, which could be crucial for resolving the issue.

Recommendation

Apply workaround: Check the ClawHub website or documentation for the correct installation instructions or slug for the skill-vetter skill, as the provided slug might be incorrect or outdated.

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…

FAQ

Expected behavior

Successfully install skill-vetter as the document(https://clawhub.ai/spclaudehome/skill-vetter) says.

Still need to ship something?

×6

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

Back to top recommendations

TRENDING