mem0ai/mem0 · error · Error
Top-level entity parameters [${invalidKeys.join(", ")}] are
Error message
Top-level entity parameters [${invalidKeys.join(", ")}] are not supported in ${methodName}(). Use filters: { user_id: "..." } instead. What it means
The hosted MemoryClient (mem0-ts/src/client/mem0.ts) has migrated entity scoping into a structured `filters` object; rejectTopLevelEntityParams() throws when legacy top-level keys (user_id, agent_id, app_id, run_id — the ENTITY_PARAMS list) appear in an options bag. It exists to break developers loudly out of the pre-v3 calling convention instead of silently ignoring scope.
Source
Thrown at mem0-ts/src/client/mem0.ts:63
"userId",
"agentId",
"appId",
"runId",
];
/**
* Validates that no top-level entity parameters are passed.
* @throws Error if entity params are found at top level
*/
function rejectTopLevelEntityParams(
options: Record<string, any> | undefined,
methodName: string,
): void {
const invalidKeys = Object.keys(options ?? {}).filter((k) =>
ENTITY_PARAMS.includes(k),
);
if (invalidKeys.length > 0) {
throw new Error(
`Top-level entity parameters [${invalidKeys.join(", ")}] are not supported in ${methodName}(). ` +
`Use filters: { user_id: "..." } instead.`,
);
}
}
function encodePathSegment(value: unknown): string {
return encodeURIComponent(String(value));
}
class APIError extends Error {
constructor(message: string) {
super(message);
this.name = "APIError";
}
}
interface ClientOptions {View on GitHub (pinned to 001c235229)
Solutions
- Move entity keys into filters: client.add(messages, { filters: { user_id: 'alice' } }).
- Grep your codebase for `user_id:`, `agent_id:`, `app_id:`, `run_id:` inside options objects passed to MemoryClient methods and rewrite each.
- Check the current TypeScript types — the options interfaces no longer declare these keys, so a typecheck usually flags them.
- Pin to the old major version only as a temporary bridge while migrating.
Example fix
// before
await client.add(messages, { user_id: "alice" });
// after
await client.add(messages, { filters: { user_id: "alice" } }); Defensive patterns
Strategy: validation
Validate before calling
const ENTITY_PARAMS = ['user_id', 'agent_id', 'app_id', 'run_id'] as const;
function toFilters(options: Record<string, any> = {}): Record<string, any> {
const filters: Record<string, any> = { ...(options.filters ?? {}) };
for (const k of ENTITY_PARAMS) {
if (k in options) {
filters[k] = options[k];
delete options[k];
}
}
return filters;
}
// migrate call sites mechanically:
await client.add(messages, { filters: toFilters(options) }); Type guard
const hasTopLevelEntityParams = (o: Record<string, any> | undefined): boolean =>
Object.keys(o ?? {}).some(k => ['user_id', 'agent_id', 'app_id', 'run_id'].includes(k)); Prevention
- Enable strict TypeScript so options bags with unknown keys are rejected at compile time.
- Codemod all `user_id:`-style options into `filters:` in one pass when upgrading to the v3 client.
- Prefer the SDK's exported option types over Record<string, any> at call sites.
When it happens
Trigger: Calling client.add(messages, { user_id: 'alice' }), client.getAll({ agent_id: 'bot' }), client.search(q, { app_id: 'x' }) — any method whose options include an ENTITY_PARAMS key at the top level triggers the throw before any network call.
Common situations: Upgrading mem0ai npm package from a v1/v2 client to the v3 API surface; copy-pasting examples from old docs or blog posts; code generators trained on the old SDK.
Related errors
- Either memoryId or --all is required
- At least one entity ID is required for deleteEntities.
- Unknown LLM provider: ${providerId}
- Unknown embedder provider: ${providerId}
- ${label} has unknown keys: ${unknown.join(", ")}
AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15).
Data as JSON: /api/errors/663872f855df30ad.
Report an issue: GitHub.