Skip to content

plugins registry --refresh (refreshReason: policy-changed) drops path/npm-origin plugins from plugins[] #89606

@cjagwani

Description

@cjagwani

Summary

When OpenClaw's plugin registry regenerates with refreshReason: "policy-changed" (which happens on the first sandbox run after a runtime policy mutation), the rebuild of plugins[] excludes any plugin whose installRecords[id].source is "path" or "npm". Only bundled extensions (origin: "bundled") survive the regen.

Impact

  • openclaw plugins inspect <id>Plugin not found
  • openclaw config set plugins.allow ... silently strips the entry because the validator only consults plugins[], not installRecords
  • TUI slash command not registered for the affected plugin
  • Plugin's own subcommand (e.g. openclaw <plugin-id>) unreachable until someone re-runs openclaw plugins registry --refresh manually

Reproduced on:

  • DGX Spark + Ubuntu 24.04 aarch64 + OpenClaw 2026.5.22 + OpenShell 0.0.44
  • Brev T4 (n1-highcpu-4:nvidia-tesla-t4:1) + Ubuntu 22.04 + same OpenClaw/OpenShell

Common factor: sandbox onboard with GPU enabled, which mutates policy between build and first runtime. No-GPU onboard does not trigger the regen and the bug does not manifest.

Evidence

Right after first sandbox run on fresh image:

{
  "refreshReason": "policy-changed",
  "installRecords": {
    "nemoclaw":        {"source": "path", "installPath": "/sandbox/.openclaw/extensions/nemoclaw"},
    "openclaw-weixin": {"source": "npm",  "spec": "@tencent-weixin/openclaw-weixin@2.4.3"}
  },
  "plugins": [ /* 93 entries — all origin: "bundled" — nemoclaw + weixin missing */ ]
}

installRecords is preserved (file is on disk, installer ran). plugins[] is rebuilt from bundled discovery only, so the runtime view forgets both entries.

Reproducer

# Any host with GPU. Tested on Brev T4 + DGX Spark.
curl -fsSL https://www.nvidia.com/nemoclaw.sh | bash -s -- --yes-i-accept-third-party-software
nemoclaw onboard --non-interactive --yes --name my-assistant \
  --agent openclaw --gpu --sandbox-gpu --fresh

SBX=$(docker ps --format '{{.Names}}' | grep '^openshell-my-assistant' | head -1)
docker exec "$SBX" cat /sandbox/.openclaw/plugins/installs.json | \
  jq '[.plugins[] | select(.id == "nemoclaw")] | length'
# → 0 (expected: 1)

Workaround

openclaw plugins registry --refresh (as the sandbox user, HOME=/sandbox) restores both plugins to the runtime registry. This works as a manual recovery but should not be required after onboard. NemoClaw is shipping a temporary post-gateway-start refresh call in their sandbox entrypoint (see related issue below); intent is to remove that workaround once this issue is fixed upstream.

Suggested fix

Either of these closes the issue:

  1. Registry regen rebuilds plugins[] from installRecords ∪ bundled discovery — not bundled only. Path/npm-origin plugins survive policy-changed regen.
  2. plugins.allow validator consults installRecords as a fallback when an id isn't in plugins[] — so users can pin plugins.allow even if the regen view is stale.

Option (1) is the cleaner fix because it removes the source-of-truth split between installRecords and plugins[].

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:otherThis issue has meaningful maintainer-visible impact outside the owned taxonomy.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions