mem0ai/mem0 · error · Error

Invalid metadata key '${metadataKey}'. Only letters, numbers

Error message

Invalid metadata key '${metadataKey}'. Only letters, numbers, underscores, nesting via '.', and array wildcards '[*]' are allowed.

What it means

Metadata keys are embedded into Oracle JSON path expressions (JSON_EXISTS / JSON_VALUE with '$.path'). The METADATA_KEY_RE allow-list (letters, digits, underscore, dot, brackets, comma, whitespace, asterisk) prevents keys containing quotes, dollar signs, or other characters that would alter the path semantics or break out into SQL. Keys failing the pattern are rejected up front.

Source

Thrown at mem0-ts/src/oss/src/vector_stores/oracledb.ts:58

  },
};

const IDENTIFIER_RE = /^(?:"[^"]+"|[^".]+)(?:\.(?:"[^"]+"|[^".]+))*$/;
const METADATA_KEY_RE = /^[a-zA-Z0-9_.[\],\s*]+$/;

export function quoteIdentifier(name: string): string {
  const trimmed = name.trim();
  if (!IDENTIFIER_RE.test(trimmed)) {
    throw new Error(`Identifier name ${name} is not valid.`);
  }
  return [...trimmed.matchAll(/"([^"]+)"|([^".]+)/g)]
    .map((m) => `"${m[1] ?? m[2]}"`)
    .join(".");
}

function jsonPath(metadataKey: string): string {
  if (!METADATA_KEY_RE.test(metadataKey)) {
    throw new Error(
      `Invalid metadata key '${metadataKey}'. Only letters, numbers, underscores, ` +
        `nesting via '.', and array wildcards '[*]' are allowed.`,
    );
  }
  return metadataKey
    .split(".")
    .map((part) =>
      part.endsWith("[*]") ? `."${part.slice(0, -3)}"[*]` : `."${part}"`,
    )
    .join("");
}

const COMPARISON_OPERATORS: Record<string, string> = {
  eq: "==",
  ne: "!=",
  gt: ">",
  gte: ">=",
  lt: "<",

View on GitHub (pinned to 001c235229)

Solutions

  1. Sanitize metadata keys at write time to the allowed character set (letters, digits, underscore, dot, [*]).
  2. Rename offending keys before querying: map 'user's name' -> 'user_name'.
  3. Enforce a key pattern in your ingestion pipeline so only safe keys reach the store.

Example fix

// before
filters = { "user's name": 'alice' };

// after
// store payload with sanitized key
filters = { user_name: 'alice' };
Defensive patterns

Strategy: validation

Validate before calling

const KEY = /^[a-zA-Z0-9_.[\],\s*]+$/;
function sanitizeKeys(payload: Record<string, any>): Record<string, any> {
  const out: Record<string, any> = {};
  for (const [k, v] of Object.entries(payload)) {
    if (!KEY.test(k)) throw new TypeError(`Illegal metadata key: ${k}`);
    out[k] = v;
  }
  return out;
}

Type guard

const isSafeMetadataKey = (k: string): boolean => /^[a-zA-Z0-9_.[\],\s*]+$/.test(k);

Prevention

When it happens

Trigger: Filtering or reading a metadata key like "user's name", 'cost$', 'a"b', or keys with slashes/hashes: filters = { "weird/key": 'x' }.

Common situations: Free-form metadata keys derived from user profiles or document attributes; migrating metadata schemas from document DBs that allow any key; i18n keys with accented characters beyond [a-zA-Z].

Related errors


AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15). Data as JSON: /api/errors/cd183b9813384baa. Report an issue: GitHub.