Skip to content

[Bug]: examples/openclaw-plugin/index.ts missing withTimeout protection (same as #673) #748

@Meskjei

Description

@Meskjei

Bug Description

PR #688 fixed the auto-recall timeout issue in examples/openclaw-memory-plugin/index.ts by wrapping the recall logic with withTimeout(). However, the plugin code was later moved to examples/openclaw-plugin/index.ts, and the fix was not synchronized to the new location.

The current code in examples/openclaw-plugin/index.ts (main branch) still has the same bug:

  • autoRecallTimeoutMs = 5_000 is defined but never used
  • withTimeout is imported but not called in the auto-recall path
  • If the OpenViking HTTP calls hang (e.g., during transient connection issues), the before_prompt_build hook blocks indefinitely, causing total agent silence

Steps to Reproduce

  1. Use the plugin from examples/openclaw-plugin/ directory
  2. Configure with autoRecall: true
  3. Have OpenViking server in a transient state (e.g., shortly after gateway restart)
  4. Send a message to the agent
  5. Agent hangs silently at before_prompt_build hook

Expected Behavior

If auto-recall does not complete within autoRecallTimeoutMs (5 seconds), the hook should:

  • Time out gracefully
  • Log a warning
  • Allow the agent to start without memory context

Actual Behavior

The hook blocks indefinitely. No response is ever sent to the user.

Root Cause

PR #688 applied the fix to examples/openclaw-memory-plugin/index.ts, but the plugin was later refactored/moved to examples/openclaw-plugin/index.ts without carrying over the timeout protection.

Proposed Fix

Apply the same fix from PR #688 to examples/openclaw-plugin/index.ts:

// Current code (line ~439):
if (cfg.autoRecall && queryText.length >= 5) {
  const precheck = await quickRecallPrecheck(...);
  if (!precheck.ok) {
    // skip
  } else {
    try {
      // ← No timeout protection here
      const candidateLimit = ...
      const [userSettled, agentSettled] = await Promise.allSettled([...]);
      // ... more awaits
    } catch (err) {
      api.logger.warn(...);
    }
  }
}

// Should be:
if (cfg.autoRecall && queryText.length >= 5) {
  const precheck = await quickRecallPrecheck(...);
  if (!precheck.ok) {
    // skip
  } else {
    try {
      await withTimeout(
        (async () => {
          // ← Wrap entire recall logic in IIFE
          const candidateLimit = ...
          const [userSettled, agentSettled] = await Promise.allSettled([...]);
          // ... more awaits
        })(),
        autoRecallTimeoutMs,
        `openviking: auto-recall timed out after ${autoRecallTimeoutMs}ms`,
      );
    } catch (err) {
      api.logger.warn(`openviking: auto-recall failed or timed out: ${String(err)}`);
    }
  }
}

Additional Context

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    In progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions