mem0ai/mem0 · error
filters must contain at least one of: user_id, agent_id, run
Error message
filters must contain at least one of: user_id, agent_id, run_id. Example: filters: { user_id: 'u1' } What it means
Thrown by Memory.search() after filter processing when the effective filters contain none of user_id, agent_id, or run_id. Search is scoped per entity in the OSS SDK, so an unscoped query is rejected rather than run across all users' memories. Note the check is on snake_case keys — top-level camelCase config keys are converted first, but arbitrary filter keys are not.
Source
Thrown at mem0-ts/src/oss/src/memory/index.ts:1415
for (const fk of Object.keys(effectiveFilters)) {
if (
!["AND", "OR", "NOT", "user_id", "agent_id", "run_id"].includes(fk) &&
typeof effectiveFilters[fk] === "object" &&
effectiveFilters[fk] !== null
) {
delete effectiveFilters[fk];
}
}
effectiveFilters = { ...effectiveFilters, ...processedFilters };
}
// Validate filters contains at least one entity ID (snake_case)
if (
!effectiveFilters.user_id &&
!effectiveFilters.agent_id &&
!effectiveFilters.run_id
) {
throw new Error(
"filters must contain at least one of: user_id, agent_id, run_id. " +
"Example: filters: { user_id: 'u1' }",
);
}
const searchStartMs = Date.now();
// Step 1: Preprocess query
const queryLemmatized = lemmatizeForBm25(query);
const queryEntities = extractEntities(query);
// Step 2: Embed query
const queryEmbedding = await this.embedder.embed(query, "search");
// Step 3: Semantic search (over-fetch for scoring pool)
const internalLimit = Math.max(topK * 4, 60);
const semanticResults = await this.vectorStore.search(
queryEmbedding,View on GitHub (pinned to 001c235229)
Solutions
- Include an entity key in filters: memory.search(q, { filters: { user_id: 'u1' } })
- Use snake_case keys inside filters (user_id, agent_id, run_id); camelCase belongs in the top-level config which is converted for you
- Combine entity scope with metadata filters: { user_id: 'u1', AND: [{ category: { equals: 'pref' } }] }
Example fix
// before
await memory.search('preferences', { filters: { userId: 'alice' } });
// after
await memory.search('preferences', { filters: { user_id: 'alice' } }); Defensive patterns
Strategy: type-guard
Validate before calling
function scopedFilters(f: Record<string, unknown> = {}) {
if (!f.user_id && !f.agent_id && !f.run_id) {
throw new Error('search requires user_id, agent_id, or run_id');
}
return f;
} Type guard
const isEntityScoped = ( f?: Partial<Record<'user_id' | 'agent_id' | 'run_id', string>>, ): boolean => Boolean(f && (f.user_id || f.agent_id || f.run_id));
Prevention
- Use snake_case entity keys inside filters; camelCase at the top level
- Type filters against the SDK's SearchFilters type so missing scope is a compile-time signal
When it happens
Trigger: Calling memory.search('query', { filters: {} }), or passing filters with only non-entity keys like { category: 'prefs' }, or passing camelCase entity keys directly inside filters ({ userId: 'u1' }) so the snake_case check misses them.
Common situations: Assuming search() without filters searches everything (it does not — use entity-scoped search); mixing camelCase into the filters object; building filters dynamically so the entity key can be absent.
Related errors
- One of the filters: userId, agentId or runId is required!
- Unsupported metadata filter operator: ${operator}
- AND operator requires a list of conditions
- OR operator requires a non-empty list of conditions
- NOT operator requires a non-empty list of conditions
AI-assisted analysis of mem0ai/mem0@001c235229 (2026-08-15).
Data as JSON: /api/errors/97579be58b3ba174.
Report an issue: GitHub.