openclaw - 💡(How to fix) Fix [Bug]: snapshot reuse misses when reader workspace differs from startup workspace (follow-up to #77519 fix) [1 comments, 2 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#77926Fetched 2026-05-06 06:19:18
View on GitHub
Comments
1
Participants
2
Timeline
3
Reactions
2
Author
Timeline (top)
commented ×1mentioned ×1subscribed ×1

The v2026.5.4 fix for #77519 (48ff390953 + a7263de258) covers readers that omit workspaceDir and hot paths that previously dropped it. There is a third path it does not cover: when a reader passes a concrete agent workspace that is not the same string as the startup snapshot's stored workspace, the snapshot is rejected on every call.

For a deployment with multiple agents that each have an explicit workspace: entry pointing to its own directory, this is the ordinary state — every non-default-agent dispatch goes through loadPluginMetadataSnapshot and runs the per-plugin stat sweep on the main thread.

Root Cause

The v2026.5.4 allowWorkspaceScopedSnapshot opt-in does not apply here because the reader has a real workspaceDir to pass.

Fix Action

Fix / Workaround

For a deployment with multiple agents that each have an explicit workspace: entry pointing to its own directory, this is the ordinary state — every non-default-agent dispatch goes through loadPluginMetadataSnapshot and runs the per-plugin stat sweep on the main thread.

  1. Configure several agents in agents.list[] with explicit workspace: paths that differ from the default workspace (e.g. one workspace dir per agent).
  2. Drive dispatch on the non-default agents (channel inbound, webchat, etc.).
  3. strace -p $GATEWAY_PID -c for 5 seconds during dispatch.

Snapshot reuse on dispatch hot paths, similar to single-workspace setups.

Code Example

% time     seconds  usecs/call     calls    errors syscall
 70.35    0.194137           3     48914           statx
  9.95    0.027445           3      6895       917 access
  8.24    0.022730           4      4564           openat
  ...
  ~67k syscalls / 5s, 70% in statx

---

// gateway startup
setCurrentPluginMetadataSnapshot(pluginLookUpTable, { config });
// snapshot.workspaceDir ends up = ~/.openclaw/workspace

---

const workspaceDir = resolveAgentWorkspaceDir(cfg, agentId);
// e.g. ~/.openclaw/workspace-<agent-id>
const snapshot = getCurrentPluginMetadataSnapshot({ config, workspaceDir });

---

if (
  params.workspaceDir !== undefined &&
  (snapshot.workspaceDir ?? "") !== (params.workspaceDir ?? "")
) {
  return undefined;
}
RAW_BUFFERClick to expand / collapse

Bug type

Regression follow-up

Summary

The v2026.5.4 fix for #77519 (48ff390953 + a7263de258) covers readers that omit workspaceDir and hot paths that previously dropped it. There is a third path it does not cover: when a reader passes a concrete agent workspace that is not the same string as the startup snapshot's stored workspace, the snapshot is rejected on every call.

For a deployment with multiple agents that each have an explicit workspace: entry pointing to its own directory, this is the ordinary state — every non-default-agent dispatch goes through loadPluginMetadataSnapshot and runs the per-plugin stat sweep on the main thread.

Steps to reproduce

  1. Configure several agents in agents.list[] with explicit workspace: paths that differ from the default workspace (e.g. one workspace dir per agent).
  2. Drive dispatch on the non-default agents (channel inbound, webchat, etc.).
  3. strace -p $GATEWAY_PID -c for 5 seconds during dispatch.

Expected

Snapshot reuse on dispatch hot paths, similar to single-workspace setups.

Actual

% time     seconds  usecs/call     calls    errors syscall
 70.35    0.194137           3     48914           statx
  9.95    0.027445           3      6895       917 access
  8.24    0.022730           4      4564           openat
  ...
  ~67k syscalls / 5s, 70% in statx

Pattern: alphabetical traversal of dist/extensions/<plugin>/{package.json,openclaw.plugin.json} for all bundled plugins, repeating while dispatch is active.

Effect on the same workload, v2026.5.3-1 vs v2026.4.27:

  • sessions.list: 156 s vs ~150 ms
  • chat.history: 96 s vs ~155 ms
  • eventLoopUtilization: 1.0 vs ~0.05
  • Discord WS heartbeat misses + simultaneous close 1000 storms
  • v2026.4.27 strace: 0 statx, ~671 total syscalls / 5s

(Numbers from the original v2026.5.3-1 reproduction; we have not yet captured a v2026.5.4 strace from the same setup — see note below.)

Where it shows up in source

Startup stores the snapshot with defaultWorkspaceDir:

// gateway startup
setCurrentPluginMetadataSnapshot(pluginLookUpTable, { config });
// snapshot.workspaceDir ends up = ~/.openclaw/workspace

Dispatch reader passes the dispatching agent's resolved workspace:

const workspaceDir = resolveAgentWorkspaceDir(cfg, agentId);
// e.g. ~/.openclaw/workspace-<agent-id>
const snapshot = getCurrentPluginMetadataSnapshot({ config, workspaceDir });

Equality check at current-plugin-metadata-snapshot.ts:80-87:

if (
  params.workspaceDir !== undefined &&
  (snapshot.workspaceDir ?? "") !== (params.workspaceDir ?? "")
) {
  return undefined;
}

Two different non-empty strings → cache miss → fallback runs safeFileSignature for every record in index.plugins.

The v2026.5.4 allowWorkspaceScopedSnapshot opt-in does not apply here because the reader has a real workspaceDir to pass.

Environment

  • v2026.5.3-1 (rolled back to v2026.4.27 to restore service)
  • Linux x86_64, Node v22.x supported / observed on v25
  • ~10+ agents with explicit per-agent workspace: config, ~96 bundled plugins, several inbound channels

Note

We have not yet run v2026.5.4 in production from this setup, so the regression is reasoned from source rather than verified against the new release. Happy to capture a v2026.5.4 strace in a controlled window if that would help.

No fix proposal here — leaving design discretion to maintainers; the safety boundary around workspace-plugin discovery is non-trivial.

Related

#77519, #77532, #77529 (closed setter-only PR), #76182, #73353

extent analysis

TL;DR

The issue can be addressed by modifying the getCurrentPluginMetadataSnapshot function to handle cases where the reader's workspace directory differs from the snapshot's stored workspace directory.

Guidance

  • Review the current-plugin-metadata-snapshot.ts file, specifically lines 80-87, to understand the equality check that causes the cache miss.
  • Consider modifying the getCurrentPluginMetadataSnapshot function to allow for a more flexible comparison of workspace directories, such as using a normalized path or ignoring certain differences.
  • Investigate the allowWorkspaceScopedSnapshot option and determine if it can be applied to this scenario, despite the reader having a real workspaceDir to pass.
  • Test the modified function with the provided reproduction steps to verify the fix.

Example

// Modified equality check
if (
  params.workspaceDir !== undefined &&
  !pathEquals(snapshot.workspaceDir, params.workspaceDir)
) {
  return undefined;
}

// Helper function to compare paths
function pathEquals(path1: string, path2: string): boolean {
  // Normalize paths and compare
  return normalizePath(path1) === normalizePath(path2);
}

// Normalize path function (implementation omitted)
function normalizePath(path: string): string {
  // ...
}

Notes

The provided code snippet is a hypothetical example and may require modifications to fit the actual implementation. The pathEquals function is a placeholder and would need to be implemented according to the specific requirements.

Recommendation

Apply a workaround by modifying the getCurrentPluginMetadataSnapshot function to handle different workspace directories, as this is a regression introduced in a recent version and a proper fix would require a deeper understanding of the underlying design.

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…

Still need to ship something?

×6

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

Back to top recommendations

TRENDING