TencentCloud/TencentDB-Agent-Memory · error

Storage key must be relative, got absolute: ${key}

Error message

Storage key must be relative, got absolute: ${key}

What it means

LocalStorageBackend.resolvePath() maps storage object keys to file paths under a configured rootDir. As part of a path-traversal security fix (CR-6), it rejects any key that starts with '/' or '\' because such keys are absolute paths and could target arbitrary filesystem locations instead of staying inside rootDir. Keys must be relative path segments joined under the backend root.

Source

Thrown at MemoryCore/src/core/storage/local-backend.ts:69

   * rootDir). Affects standalone mode where user-controllable fields like
   * instanceId / sceneName / sessionKey end up in the key.
   *
   * Rejected:
   * - Empty key
   * - Keys containing NUL (\0) — POSIX/Linux path terminator, can confuse
   *   downstream tooling (sqlite, file managers).
   * - Keys with leading "/" or "\" (absolute paths).
   * - Keys whose resolved path falls outside rootDir (../ traversal).
   */
  private resolvePath(key: string): string {
    if (!key || typeof key !== "string") {
      throw new Error(`Invalid storage key: ${JSON.stringify(key)}`);
    }
    if (key.includes("\0")) {
      throw new Error("Storage key must not contain NUL character");
    }
    if (key.startsWith("/") || key.startsWith("\\")) {
      throw new Error(`Storage key must be relative, got absolute: ${key}`);
    }

    // Normalize key separators to OS path separators
    const normalized = key.split("/").join(sep);

    // Compute the absolute resolved path; resolve() collapses ".." segments.
    const absRoot = resolve(this.rootDir);
    const absResolved = resolve(absRoot, normalized);

    // Ensure the resolved path stays inside rootDir. Append sep so that
    // a key like "../rootDir2/foo" (which resolves to a sibling directory
    // whose name happens to start with rootDir's name) is also rejected.
    const rootWithSep = absRoot.endsWith(sep) ? absRoot : absRoot + sep;
    if (absResolved !== absRoot && !absResolved.startsWith(rootWithSep)) {
      throw new Error(`Path traversal rejected: key "${key}" escapes rootDir`);
    }

    return absResolved;

View on GitHub (pinned to 3efcd317b8)

Solutions

  1. Strip leading '/' or '\\' (and collapse duplicate separators) from the key before passing it to the backend.
  2. Fix the source of the key (config or user input) so it is stored as a relative path segment; validate at ingestion.
  3. If an absolute path is genuinely needed, configure the backend's rootDir to that location and use a relative key instead.

Example fix

// before
const key = `${sessionKey}/memory.json`; // sessionKey = "/data/instances/abc"
await storage.putObject(key, data);
// after
const relKey = sessionKey.replace(/^[\\/]+/, "");
const key = `${relKey}/memory.json`;
await storage.putObject(key, data);
Defensive patterns

Strategy: validation

Validate before calling

function isSafeRelativeKey(key: string): boolean {
  return typeof key === "string" && key.length > 0 && !key.startsWith("/") && !key.startsWith("\\") && !key.includes("\0");
}
if (!isSafeRelativeKey(key)) throw new Error(`key must be relative: ${key}`);

Type guard

function isRelativeKey(key: unknown): key is string {
  return typeof key === "string" && key.length > 0 && !key.startsWith("/") && !key.startsWith("\\");
}

Try / catch

try {
  await storage.putObject(key, data);
} catch (e) {
  if (e instanceof Error && e.message.startsWith("Storage key must be relative")) {
    key = key.replace(/^[\\/]+/, "");
    await storage.putObject(key, data);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling putObject/getObject/appendObject/list (any method that calls resolvePath) with a key that begins with '/' (POSIX absolute, e.g. '/etc/passwd') or '\\' (Windows absolute, e.g. '\\\\server\\share\\file'). Commonly produced by joining user-controlled fields like instanceId, sceneName or sessionKey that already contain a leading slash into the key template.

Common situations: A config value such as sessionKey or instanceId was set to an absolute path by mistake; code migrated from an API that accepted absolute paths; string concatenation like root + '/' + key where key already starts with '/'; on Windows, UNC paths ('\\\\server\\share') pasted into a config field.

Related errors


AI-assisted analysis of TencentCloud/TencentDB-Agent-Memory@3efcd317b8 (2026-09-01). Data as JSON: /api/errors/1376fe8affc4cc09. Report an issue: GitHub.