Skip to content

[Bug] autoRecall passes untrusted metadata tags as search queries #24

Description

@Alex-bytedance

Problem Description

The autoRecall feature in index.ts passes raw message content (including OpenClaw metadata tags) as search queries to the PowerMem CLI, causing search failures with Error 404.

Observed Behavior

From gateway logs:

memory search Conversation info (untrusted metadata):
程嘉: powermemo有没有修复好? --user-id alex --agent-id dalu --limit 15

And:

memory search System (untrusted): [2026-04-10 07:33:13 GMT+8] Exec completed...

The search query includes:

  • Conversation info (untrusted metadata): header
  • System (untrusted): header
  • [message_id: ...] tags
  • JSON code blocks with sender metadata

Root Cause

In index.ts lines 441-448, the before_agent_start hook extracts query from e.prompt or lastUserMessageText(e.messages) without filtering out OpenClaw metadata tags:

const query =
  (typeof e.prompt === "string" && e.prompt.trim().length >= 5
    ? e.prompt.trim()  // This includes the full prompt with metadata tags
    : lastUserMessageText(e.messages)) || "";

The lastUserMessageText function (lines 418-440) also doesn't filter these tags.

Impact

  • All autoRecall searches fail with Error 404
  • Gateway logs show repeated failures
  • Memory context is not injected into agent prompts

Proposed Fix

Add a helper function to sanitize queries by removing:

  1. Conversation info (untrusted metadata): headers
  2. System (untrusted): headers
  3. [message_id: ...] tags
  4. JSON code blocks containing "sender", "timestamp", etc.

Example:

function sanitizeQuery(raw: string): string {
  // Remove metadata headers
  let cleaned = raw
    .replace(/Conversation info \(untrusted metadata\):\s*/gi, "")
    .replace(/System \(untrusted\):\s*/gi, "")
    .replace(/Sender \(untrusted metadata\):\s*/gi, "")
    .replace(/\[message_id:\s*[\w]+\]\s*/g, "");
  
  // Remove JSON code blocks with metadata
  cleaned = cleaned.replace(/\\\/gi, "");
  
  // Extract actual user message after metadata
  const match = cleaned.match(/^[^:]+:\s*(.+)$/m);
  if (match && match[1]) {
    return match[1].trim();
  }
  
  return cleaned.trim();
}

Then use it in before_agent_start:

const rawQuery = (typeof e.prompt === "string" && e.prompt.trim().length >= 5
  ? e.prompt.trim()
  : lastUserMessageText(e.messages)) || "";
const query = sanitizeQuery(rawQuery);

Environment

  • OpenClaw: 2026.4.9
  • memory-powermem: 0.3.0
  • Node.js: v22.22.2
  • pmem CLI: working correctly when used manually

Verification

Direct CLI test works:

pmem memory search "OpenClaw 配置" --user-id alex --limit 5
# Returns: Found 1 results

But autoRecall fails because it passes Conversation info (untrusted metadata):...程嘉: OpenClaw 配置 as the query.


Thanks for maintaining this plugin!

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions