openclaw - 💡(How to fix) Fix [Bug]: openviking plugin can leak agent context via shared mutable client agentId [3 comments, 3 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#52145Fetched 2026-04-08 01:15:09
View on GitHub
Comments
3
Participants
3
Timeline
4
Reactions
0
Timeline (top)
commented ×3cross-referenced ×1

Root Cause

This is not just a correctness bug. It can break agent isolation and cause cross-agent memory leakage.

Potential outcomes:

  • agent A reads memories intended for agent B
  • agent A writes/extracts into agent B's space
  • recall/capture behavior becomes nondeterministic under concurrency

Code Example

client.setAgentId(resolvedAgentId)

---

client.find(query, { agentId })
client.read(uri, { agentId })
RAW_BUFFERClick to expand / collapse

Problem

The OpenClaw openviking context-engine plugin appears to use a shared mutable client whose agentId is reassigned per session/request.

This creates a concurrency risk: when multiple sessions or agents hit the shared client at the same time, one request can overwrite the agentId intended for another.

Why this matters

This is not just a correctness bug. It can break agent isolation and cause cross-agent memory leakage.

Potential outcomes:

  • agent A reads memories intended for agent B
  • agent A writes/extracts into agent B's space
  • recall/capture behavior becomes nondeterministic under concurrency

Observed code shape

Local review of the OpenClaw openviking plugin showed this pattern across:

  • index.ts
  • context-engine.ts
  • client.ts

The plugin caches/shares an OpenVikingClient, then mutates per-request identity via a method like:

client.setAgentId(resolvedAgentId)

and later reuses that same client for find/read/write/extract operations.

If another session changes the same client instance before the first request finishes, the wrong agentId can be applied.

Expected behavior

Agent identity should be request-scoped or instance-scoped, not shared mutable state.

Safer shapes include:

  • pass agentId explicitly on each request
  • construct a separate client per agent/session
  • avoid mutable shared identity on the client object

Suggested fix direction

Option A

Make OpenVikingClient stateless with respect to agentId:

client.find(query, { agentId })
client.read(uri, { agentId })

Option B

Create one client instance per agent/session and never mutate shared client identity.

Impact level

This looks like a critical isolation bug for multi-agent / concurrent usage.

Single-user serial usage may hide it, but shared or concurrent workloads can surface cross-agent contamination.

extent analysis

Fix Plan

To address the concurrency risk and isolation bug, we will implement Option A: make OpenVikingClient stateless with respect to agentId. This involves modifying the client methods to accept agentId as a parameter.

Step-by-Step Solution:

  • Update the OpenVikingClient class to remove the setAgentId method and modify the find, read, write, and extract methods to accept agentId as an option.
  • Example code:
// Before
class OpenVikingClient {
  private agentId: string;

  setAgentId(agentId: string) {
    this.agentId = agentId;
  }

  find(query: string) {
    // use this.agentId
  }

  read(uri: string) {
    // use this.agentId
  }
}

// After
class OpenVikingClient {
  find(query: string, options: { agentId: string }) {
    // use options.agentId
  }

  read(uri: string, options: { agentId: string }) {
    // use options.agentId
  }
}
  • Update the plugin code to pass agentId explicitly when calling the client methods:
const client = new OpenVikingClient();
client.find(query, { agentId: resolvedAgentId });
client.read(uri, { agentId: resolvedAgentId });

Verification

To verify the fix, test the plugin with multiple concurrent requests from different agents and ensure that each request uses the correct agentId. You can use a testing framework to simulate concurrent requests and verify the results.

Extra Tips

  • Consider adding logging or monitoring to detect any potential issues with agentId mismatch.
  • Review the plugin code to ensure that there are no other shared mutable states that could cause similar concurrency issues.

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

Agent identity should be request-scoped or instance-scoped, not shared mutable state.

Safer shapes include:

  • pass agentId explicitly on each request
  • construct a separate client per agent/session
  • avoid mutable shared identity on the client object

Still need to ship something?

×6

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

Back to top recommendations

TRENDING