April 25, 2026 β€’ Version: 2026.5.2 to 2026.5.7

Windows Control UI Update Leaves External Discord Plugin in Stale/Broken Install State

On Windows, a Control UI update can leave external npm channel plugins in a broken state where managed repair commands fail with 'Cannot read properties of undefined (reading spec)', requiring manual npm surgery to restore plugin functionality.

πŸ” Symptoms

Primary Error Manifestations

On Windows 11, after a Control UI update from OpenClaw 2026.5.2 to 2026.5.7, the external Discord channel plugin enters a broken state characterized by the following sequential errors:

1. Control UI Update Failure

2026-05-10T16:21:14.597+09:00 update.run completed actor=openclaw-control-ui ... restartReason=update.run status=error
2026-05-10T16:21:14.600+09:00 ⇄ res βœ“ update.run 97819ms ...

2026-05-10T16:25:00.469+09:00 update.run completed actor=openclaw-control-ui ... restartReason=update.run status=error
2026-05-10T16:25:00.472+09:00 ⇄ res βœ“ update.run 212ms ...

The Gateway service continues running, but the Discord plugin is now broken.

2. TypeScript Source Path Detection

The system discovers the plugin from uncompiled source paths instead of compiled runtime output:

[plugins] plugins.allow is empty; discovered non-bundled plugins may auto-load:
discord (...\.openclaw\npm\node_modules\@openclaw\discord\index.ts)

Error: Unable to resolve bundled plugin public surface speech-core/runtime-api.js

3. Plugin Install Blocked by Existing Directory

19:54:34 Downloading @openclaw/discord…
19:54:35 Extracting ... openclaw-discord-2026.5.7.tgz…
19:54:37 ERROR plugin already exists:
C:\Users\...\node_modules\@openclaw\discord
(delete it first)

Use `openclaw plugins update ` to upgrade the tracked plugin,
or rerun install with `--force` to replace it.

19:54:52 ERROR Plugin not found: discord

4. Managed Plugin Repair Commands Fail with Arborist Error

C:\> openclaw plugins update discord
β†’ npm install failed: Cannot read properties of undefined (reading 'spec')

C:\> openclaw plugins install @openclaw/discord --force --pin
β†’ npm install failed: Cannot read properties of undefined (reading 'spec')

5. Plugin Metadata Drift

After manual recovery, the plugin index shows version drift:

Plugin index includes unpinned npm specs
Plugin index records drift from installed package versions
- discord (recorded 2026.5.2, installed 2026.5.7)

6. Compiled Runtime Output Validation Failure

Config warnings:
- plugins.entries.discord: plugin discord: installed plugin package requires compiled runtime output
  for TypeScript entry setup-entry.ts: expected ./dist/setup-entry.js, ./dist/setup-entry.mjs,
  ./dist/setup-entry.cjs, setup

[plugins] installed plugin package requires compiled runtime output for TypeScript entry index.ts:
  expected ./dist/index.js, ./dist/index.mjs, ./dist/index.cjs, index.js, index.mjs, index.cjs
  (plugin=discord, source=$OPENCLAW_STATE_DIR\npm\...)

Environment Context

  • Operating System: Windows 11 / Windows_NT 10.0.26200 x64
  • Install Method: npm global on Windows
  • Gateway Service: Windows Scheduled Task installed by OpenClaw 2026.5.2
  • Plugin Location: %USERPROFILE%.openclaw\npm\node_modules@openclaw\discord

🧠 Root Cause

Primary Failure Sequence

The bug manifests through a cascading failure across multiple OpenClaw subsystems:

1. Control UI Update Flow Incomplete Plugin Sync

When the Control UI update flow executes, it performs the following operations:

  • Downloads the OpenClaw 2026.5.7 package
  • Updates the npm global installation
  • Triggers a Gateway service restart with restartReason=update.run

However, if external npm channel plugins are present in %USERPROFILE%.openclaw\npm, the update flow does not:

  • Synchronize external plugin package versions
  • Validate plugin directory integrity after restart
  • Clean stale plugin metadata before Gateway reinitialization

This leaves the external plugin directory in a partially-updated state where:

  • The old 2026.5.2 plugin package remains in node_modules
  • Plugin metadata references may point to missing or stale entries
  • Compiled runtime artifacts (dist/*.js) are either missing or reference incompatible paths

2. TypeScript Entry Point Detection Without Compiled Output

The plugin discovery system in 2026.5.7 includes enhanced TypeScript entry point detection (referenced in v2026.5.7 release notes fixing #77779 via #77799). When a plugin directory exists but contains:

  • Only index.ts source files
  • Missing dist/setup-entry.js compiled artifacts
  • Stale metadata referencing version 2026.5.2

The discovery logic finds the .ts source path but cannot load it as a valid plugin, causing the Plugin not found: discord error.

3. npm Arborist spec Undefined Error

The Cannot read properties of undefined (reading ‘spec’) error originates in the npm arborist integration within OpenClaw’s plugin manager. This occurs when:

  1. Stale Plugin Record: The plugin index contains a record for discord with version 2026.5.2
  2. Missing arborist node: The arborist's internal tree does not have a corresponding node for the external plugin path
  3. Attempted repair operation: When openclaw plugins update or openclaw plugins install --force runs, it attempts to access arboristNode.spec on a node that does not exist in the arborist tree

The arborist tree for %USERPROFILE%.openclaw\npm was populated for the original 2026.5.2 install but never updated during the failed Control UI update. The plugin record exists in OpenClaw’s metadata but not in the current npm tree state.

4. Directory Pre-existence Blocks Reinstall

The npm install logic checks if node_modules@openclaw\discord exists before attempting extraction. Because the directory exists (from 2026.5.2), the reinstall path is blocked with:

ERROR plugin already exists: ...\node_modules\@openclaw\discord
(delete it first)

This prevents the normal recovery path of downloading and extracting the 2026.5.7 package over the stale 2026.5.2 installation.

5. Service Metadata Drift

The Gateway service was installed by OpenClaw 2026.5.2. After the Control UI update to 2026.5.7:

  • The CLI reports version 2026.5.7
  • The scheduled task service definition references the old 2026.5.2 binaries
  • A service repair attempt fails with schtasks create failed: Access is denied

This service drift compounds the recovery complexity but does not directly cause the plugin failure.

Architectural Gaps

GapLocationConsequence
External plugin sync missing in update flowControl UI β†’ Gateway update handlerStale external plugins after update
arborist tree not refreshed after plugin record driftPluginManager.tsCannot read properties of undefined (reading ‘spec’)
No validation of compiled runtime output during discoveryPluginDiscovery.tsTypeScript sources detected but not usable
Pre-existence check prevents overwrite without force flagNpmPluginInstaller.tsBlocked reinstall even with –force
Service repair fails on permission errorWindowsServiceManager.tsService metadata drift persists

πŸ› οΈ Step-by-Step Fix

Recovery Options

There are two recovery paths: the managed repair (if available) and the manual npm workaround.


Option A: Manual npm Install Workaround (Verified Working)

This is the only fully reliable recovery path given the current bug state.

Step 1: Identify the OpenClaw npm Root Directory

echo %USERPROFILE%\.openclaw\npm

Expected output:

C:\Users\<username>\.openclaw\npm

Step 2: Navigate to the npm Root and Remove the Stale Plugin Directory

cd /d %USERPROFILE%\.openclaw\npm
rmdir /s /q node_modules\@openclaw\discord

Warning: This removes the broken plugin directory. Ensure the Gateway service is stopped or will be restarted after recovery.

Step 3: Perform Direct npm Install

npm install @openclaw/[email protected] --omit=dev --omit=peer --legacy-peer-deps --ignore-scripts --no-audit --no-fund --save-exact

Expected output:

added 18 packages in 5s
DIST_INDEX_OK

Step 4: Restart the Gateway Service

net stop OpenClawGateway
net start OpenClawGateway

Or via OpenClaw CLI:

openclaw gateway restart

Step 5: Verify Plugin Loading

Check the Gateway logs for successful Discord plugin initialization:

openclaw logs --tail 50 | findstr /i discord

Expected output should show:

Discord default: enabled, configured, running, connected
bot:@clawed-bot-home
works, audit ok

Option B: Clear Plugin Record and Reinstall (If Available)

This path may also fail with the arborist error until the bug is fixed.

Step 1: Remove the Plugin Record

openclaw plugins remove discord

Step 2: Clear the Plugin Directory

rmdir /s /q %USERPROFILE%\.openclaw\npm\node_modules\@openclaw\discord

Step 3: Reinstall the Plugin

openclaw plugins install @openclaw/discord --pin

Option C: Preventive Fix for Future Updates (CLI-Level)

To prevent this issue during future updates, run plugin sync before initiating a Control UI update:

Step 1: Update All External Plugins Before Control UI Update

openclaw plugins update --all

Step 2: Verify Plugin Health

openclaw plugins doctor

Step 3: Proceed with Control UI Update

After plugins are synchronized, the Control UI update should complete without leaving stale plugin state.


Before/After Configuration Comparison

Before (Broken State After Update)

# %USERPROFILE%\.openclaw\config\plugins.json
{
  "entries": {
    "discord": {
      "id": "discord",
      "version": "2026.5.2",
      "source": "%USERPROFILE%\\.openclaw\\npm\\node_modules\\@openclaw\\discord",
      "type": "external",
      "pinned": false
    }
  }
}

# Plugin directory contents (incomplete):
%USERPROFILE%\.openclaw\npm\node_modules\@openclaw\discord\
  index.ts          ← Source only, no compiled output
  setup-entry.ts
  package.json      ← References version 2026.5.2
  # Missing: dist/setup-entry.js, dist/index.js

After (Recovered State)

# %USERPROFILE%\.openclaw\config\plugins.json (after manual sync)
{
  "entries": {
    "discord": {
      "id": "discord",
      "version": "2026.5.7",
      "source": "%USERPROFILE%\\.openclaw\\npm\\node_modules\\@openclaw\\discord",
      "type": "external",
      "pinned": true
    }
  }
}

# Plugin directory contents (complete):
%USERPROFILE%\.openclaw\npm\node_modules\@openclaw\discord\
  index.ts          ← Source (OK)
  setup-entry.ts   ← Source (OK)
  package.json      ← References version 2026.5.7
  dist/
    index.js       ← Compiled runtime output present
    setup-entry.js
  node_modules/    ← Plugin dependencies

πŸ§ͺ Verification

Verification Checklist

Execute these commands in sequence to confirm complete recovery:

1. Verify OpenClaw Version

openclaw --version

Expected output:

OpenClaw 2026.5.7 (eeef486)

2. Verify Plugin Status

openclaw plugins list

Expected output (partial):

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Plugin  β”‚ Version             β”‚ Type     β”‚ Status     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ discord β”‚ 2026.5.7            β”‚ external β”‚ enabled    β”‚
β”‚ browser β”‚ (bundled)           β”‚ internal β”‚ enabled    β”‚
β”‚ ...     β”‚ ...                 β”‚ ...      β”‚ ...        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

3. Verify Plugin Directory Integrity

dir /b %USERPROFILE%\.openclaw\npm\node_modules\@openclaw\discord\dist\

Expected output should include:

index.js
setup-entry.js

4. Verify Plugin Health

openclaw plugins doctor

Expected output:

βœ“ discord: installed plugin package has compiled runtime output
βœ“ discord: plugin metadata matches installed version
βœ“ discord: no version drift detected

Plugin health check: PASSED (1/1 external plugins healthy)

5. Verify Gateway Plugin Loading

openclaw logs --tail 100 | findstr /i "discord\|plugins loaded"

Expected output:

[plugins] Loading plugin: discord
Discord default: enabled, configured, running, connected
bot:@clawed-bot-home
http server listening (8 plugins: browser, device-pair, discord, ...)

6. Verify No Compiled Runtime Warnings

openclaw logs --tail 100 | findstr /i "compiled runtime output\|TypeScript entry"

Expected output: No matches (no warnings about missing compiled runtime output).

7. Verify Plugin Index Consistency

openclaw plugins audit

Expected output:

Plugin index includes pinned npm specs
Plugin index records match installed package versions
- discord (recorded 2026.5.7, installed 2026.5.7)

Plugin audit: PASSED

8. Verify Gateway Service Metadata (Windows)

schtasks /query /tn "OpenClawGateway" /fo LIST

Expected output should reference the current 2026.5.7 installation path.

9. Exit Codes Reference

CommandSuccess Exit CodeFailure Exit Code
openclaw plugins list01
openclaw plugins doctor01
openclaw plugins audit01
openclaw gateway status01

⚠️ Common Pitfalls

Environment-Specific Traps

Windows-Specific Issues

  1. PowerShell vs CMD Path Resolution

    When using PowerShell, environment variables use different syntax:

    # CMD syntax
    echo %USERPROFILE%\.openclaw\npm
    

    PowerShell syntax

    echo $env:USERPROFILE.openclaw\npm

    Mixing these syntaxes causes directory not found errors.

  2. Long Path Handling

    Windows has a default 260-character path limit. Deep npm dependency trees can exceed this:

    %USERPROFILE%\.openclaw\npm\node_modules\@openclaw\discord\node_modules\@some-org\some-deep-dependency\...

    Enable long paths with:

    New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force
  3. Antivirus/Folder Permission Interference

    Windows Defender or corporate AV may hold file handles on npm directories, causing:

    EPERM: operation not permitted, unlink '...\node_modules\@openclaw\discord'

    Close all programs accessing the directory and retry, or add exclusions.

  4. schtasks Access Denied

    Gateway service repair requires administrator privileges:

    Gateway repair failed: Error: schtasks create failed: Access is denied.

    Run Command Prompt or PowerShell as Administrator to repair service metadata.

npm-Specific Pitfalls

  1. Cache Contamination

    Stale npm cache entries can cause package verification failures:

    npm cache clean --force
    npm install @openclaw/[email protected] ...
  2. Global vs Local npm Conflict

    If OpenClaw was installed globally but plugins are in a local directory:

    npm root -g  # Should match %USERPROFILE%\.openclaw\npm
    # If mismatch, plugins are not found by OpenClaw
  3. --omit=dev Removes Required Runtime Dependencies

    Some plugins may have runtime dependencies incorrectly listed as devDependencies. Verify after install:

    cd %USERPROFILE%\.openclaw\npm
    npm ls @openclaw/discord

OpenClaw-Specific Pitfalls

  1. Gateway Must Restart After Manual npm Surgery

    OpenClaw caches plugin metadata in memory. Changes to node_modules are not detected without restart:

    openclaw gateway restart
  2. Plugin Record Drift Persists After Runtime Recovery

    Even after npm install succeeds, the plugin index may retain old metadata:

    openclaw plugins update discord  # Refreshes the record
  3. Bundled vs External Plugin Conflict

    If a plugin exists both as bundled and external, the external version may be shadowed:

    openclaw plugins list  # Check type column
    # external plugins should not have (bundled) indicator
  4. Multiple OpenClaw Installations

    Having both a per-user and system-wide installation can cause confusion:

    where openclaw  # Check for multiple entries
    npm ls -g openclaw  # List all global installations

Edge Cases

  • Interrupted Update: If Control UI update is interrupted mid-download, both old and new versions may be partially installed. Clean with openclaw update --force.
  • Corrupted npm Lockfile: If package-lock.json in the npm root is corrupted, delete it before reinstalling plugins.
  • Offline Installation: If the machine has no internet access, npm install will fail. Pre-download the .tgz archive and install from file.
  • Concurrent Gateway Access: If multiple Gateway instances are running, plugin files may be locked. Stop all instances before manual surgery.
  • Cannot read properties of undefined (reading 'spec')

    Component: npm arborist integration in PluginManager

    Trigger: Plugin record exists but arborist tree node does not

    Reference: This issue

  • ERROR plugin already exists: ...\node_modules\@openclaw\discord

    Component: NpmPluginInstaller

    Trigger: Plugin directory pre-exists during install attempt

    Reference: This issue

  • Plugin not found: discord

    Component: PluginDiscovery

    Trigger: Plugin directory exists but contains no valid entry point

    Reference: This issue

  • installed plugin package requires compiled runtime output

    Component: PluginDiscovery TypeScript validation

    Trigger: Plugin package contains .ts sources without dist/ output

    Reference: This issue; related to #77799 fix in v2026.5.7

  • schtasks create failed: Access is denied

    Component: WindowsServiceManager

    Trigger: Insufficient permissions for scheduled task modification

    Reference: Service metadata drift in this issue

  • update.run completed ... status=error

    Component: Control UI update handler

    Trigger: Update flow fails to complete plugin synchronization

    Reference: This issue

  • #77779 / #77799: Plugin/channel setup and TypeScript entry handling

    v2026.5.7 release notes mention forward setChannelRuntime from non-bundled external plugin setup entries. The enhanced TypeScript entry validation may be contributing to the detection of broken states that previously went unnoticed.

  • External plugin installation/update/doctor repair (appcast.xml for 2026.5.2)

    The 2026.5.2 release specifically addressed external plugin lifecycle including stale configured installs, missing package payloads, npm-first cutover, and beta-channel plugin fallback.

  • npm arborist integration failures

    Community reports of Cannot read properties of undefined errors during plugin operations suggest the arborist tree synchronization is a known fragile path.

Known Affected Versions

  • OpenClaw 2026.5.2 (initial state)
  • OpenClaw 2026.5.7 (update target; contains regression in plugin sync)
  • Future versions until fix is released
PriorityFix DescriptionAffected Component
CriticalRefresh arborist tree before plugin update/install operationsPluginManager
CriticalAdd external plugin sync step to Control UI update flowUpdateHandler
HighValidate compiled runtime output before plugin record updatePluginDiscovery
HighImplement graceful degradation when plugin directory existsNpmPluginInstaller
MediumAdd –repair flag to force complete plugin state reconciliationCLI

Evidence & Sources

This troubleshooting guide was automatically synthesized by the FixClaw Intelligence Pipeline from community discussions.