Skip to content

runBackup() fails on every run under OpenClaw 2026.7 — api.resolvePath() returns undefined for '..' traversal #992

Description

@israelkalush-lgtm

Summary

The daily auto-backup has failed on every execution since upgrading to OpenClaw v2026.7.1-2. The .. path traversal used to derive the backup directory returns undefined from api.resolvePath(), and the subsequent mkdir() throws. The failure is caught and logged at warn level, so backups stop silently — ours went unnoticed for four and a half months while the store grew from 60 to 137 memories.

Environment

Plugin memory-lancedb-pro@1.1.0-beta.9 (current beta dist-tag)
OpenClaw 2026.7.1-2 (0790d9f)
Node 24.19.0
OS macOS 26.5.1 (arm64)
Store 137 memories, LanceDB at ~/.openclaw/memory/lancedb-pro
Install external / global (~/.openclaw/extensions/)

Observed

[plugins] memory-lancedb-pro: backup failed: TypeError [ERR_INVALID_ARG_TYPE]:
The "path" argument must be of type string or an instance of Buffer or URL. Received undefined

Fires ~60s after every gateway start (index.ts:3144), then every 24h. Last backup the plugin successfully wrote: 2026-04-07, immediately before the OpenClaw upgrade.

Expected

A dated memory-backup-YYYY-MM-DD.jsonl in <dbPath>/../backups/, as it did before OpenClaw 2026.7.

Root cause

index.ts:3011:

const backupDir = api.resolvePath(
  join(resolvedDbPath, "..", "backups"),
);
await mkdir(backupDir, { recursive: true });   // ← throws: backupDir is undefined

The undefined comes from api.resolvePath(), not from join(). Node distinguishes the two by one clause:

  • path.join(undefined, …)The "path" argument must be of type string. Received undefined
  • fs.mkdir(undefined)The "path" argument must be of type string **or an instance of Buffer or URL**. Received undefined

The logged message contains the Buffer/URL clause, so join() returned a valid string and api.resolvePath() returned undefined.

This is the only api.resolvePath() call in the plugin whose argument contains a .. segment. The other two — config.dbPath (index.ts:1594) and config.mdMirror.dir (index.ts:1524) — pass non-traversing paths and work correctly; the store reads and writes normally throughout, so this is specific to the traversal.

OpenClaw's own path helpers in dist reject upward traversal by returning undefined rather than throwing:

if (!relative || relative.startsWith("..") || path.isAbsolute(relative)) return;

This strongly suggests the 2026.7 plugin sandbox applies the same rule to api.resolvePath, making any ..-based derivation silently return undefined.

Suggested fix

Derive the sibling directory without traversing upward. dirname is already imported at index.ts:8, so this needs no new import:

-        const backupDir = api.resolvePath(
-          join(resolvedDbPath, "..", "backups"),
-        );
+        const backupDir = api.resolvePath(
+          join(dirname(resolvedDbPath), "backups"),
+        );

Two secondary suggestions

  1. Backup failure shouldn't be warn-only and silent. A backup subsystem failing every run for months without escalating is arguably the more serious half of this bug. Consider escalating after N consecutive failures, or exposing a last-successful-backup timestamp in memory-pro stats so it's visible without log archaeology.

  2. Guard the resolvePath return value. Returning undefined rather than throwing means any future sandbox tightening produces this same class of silent breakage elsewhere in the plugin. An explicit null check with a clear error message would turn a multi-step investigation into a five-minute fix.

Workaround for other users

The export CLI doesn't go through the broken path and produces an equivalent artifact:

openclaw memory-pro export --output ~/.openclaw/memory/backups/memory-backup-$(date +%F).json

Omit --scope. --scope global exported only 18 of our 137 memories while still reporting success — verify the resulting record count against openclaw memory-pro stats rather than trusting the CLI's success line.

Metadata

Metadata

Assignees

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