Skip to content

[Bug]: Plugin update emits spurious 'unsupported npm spec' error after transient npm view failure #77616

Description

@slideshow-dingo

Bug type: Behavior bug (incorrect output/state without crash)

Summary: Plugin update check emits "Could not check X before update; falling back to installer path: npm view produced incomplete package metadata" followed by "Failed to update X: unsupported npm spec: use an exact version or dist-tag (ranges are not allowed)" — the second message is a spurious spec-validation error that does not reflect the actual problem (transient npm registry metadata fetch failure).

Steps to reproduce:

  1. Run openclaw update --yes (or any workflow that triggers updatePluginsAfterCoreUpdate)
  2. Observe the post-update doctor output or gateway logs

Expected behavior: Transient npm registry metadata failures during plugin update checks should retry gracefully or produce a clear transient-network error message, not a spec-validation error that implies the spec itself is invalid.

Actual behavior:

Could not check acpx before update; falling back to installer path: npm view produced incomplete package metadata
Failed to update acpx: unsupported npm spec: use an exact version or dist-tag (ranges are not allowed)

The effectiveSpec is correctly "[email protected]" throughout the pipeline — not a range, not an invalid spec. The error "unsupported npm spec" is misleading.

OpenClaw version: 2026.5.3-1 (2eae30e)

Operating system: Linux 6.8.0-110-generic x64

Install method: npm global + plugin-managed npm root at ~/.openclaw/npm/

Model: minimax-portal/MiniMax-M2.7

Provider / routing chain: openclaw gateway -> discord channel

Additional provider/model setup details:

  • Plugin package (acpx ACP runtime) installed at ~/.openclaw/extensions/package
  • installs.json record: spec: "[email protected]", resolvedName: "acpx", version: "0.5.3"
  • Plugin is NOT a bundled plugin — acpx is not in resolveBundledPluginSources
  • Official plugin catalog entry id: "acpx" has npmSpec: "@openclaw/acpx" (different package)

Logs, screenshots, and evidence:

# Live trace confirms effectiveSpec is correct
resolveNpmUpdateSpecs({record: {spec:"[email protected]"}}) → {installSpec: "[email protected]", recordSpec: "[email protected]"}

# Direct npm view succeeds in isolation (10/10 tests)
$ npm view "[email protected]" name version dist.integrity dist.shasum --json
→ {name:"acpx", version:"0.5.3", dist.integrity:"sha512-..."}  EXIT:0

# Root cause: transient npm view failure during concurrent update
# When npm registry is slow/loaded, resolveNpmSpecMetadata returns:
#   {ok: false, error: "npm view produced incomplete package metadata"}
# Fallback path then calls installPluginFromNpmSpec, which validates the spec.
# If the fallback call also fails transiently, the error surfaces as
# "unsupported npm spec" — which is a validation-layer error, not a network error.

# Key source locations (dist bundle):
# - resolveNpmSpecMetadata: dist/install-source-utils-ZBCr6ky5.js
# - installPluginFromNpmSpec: dist/install-C_GuuNz6.js
# - updateNpmInstalledPlugins: dist/update-BGcplvG1.js

Impact and severity:

  • Affected: Any user running openclaw update or triggering post-update plugin sync
  • Severity: Low (spurious misleading error message, update itself may proceed or retry successfully)
  • Frequency: Intermittent — only occurs when npm registry returns incomplete metadata under load
  • Consequence: Confusing error message, triggers unnecessary fallback logic, makes debugging actual update failures harder

Additional information:
Two separate concerns:

  1. Transient metadata failure (primary): resolveNpmSpecMetadata calls npm view with a 60s wall-clock timeout but no output-progress timeout. If npm returns partial JSON before the full response, normalizeNpmViewMetadata gets incomplete data and returns null, producing the "incomplete package metadata" error. Fix: add noOutputTimeoutMs (e.g. 30s) and retry with backoff (2 attempts × 2s delay).

  2. Spec mismatch in beta fallback (secondary, speculative): If updateChannel = "beta", resolveNpmUpdateSpecs returns installSpec: "acpx@beta" after beta-target resolution. If that metadata fetch fails and the beta fallback kicks in, it tries "acpx@beta" as the fallback spec. parseRegistryNpmSpec("acpx@beta") returns null with "unsupported npm spec: use an exact version or dist-tag (ranges are not allowed)" because "beta" fails the DIST_TAG_RE regex — suggesting the beta tag itself is considered invalid when it should be accepted as a dist-tag.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:needs-live-reproClawSweeper needs live local, crabbox, or manual validation to confirm this issue.impact:otherThis issue has meaningful maintainer-visible impact outside the owned taxonomy.issue-rating: 🐚 platinum hermitGood issue quality with a plausible reproduction path needing some confirmation.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions