rohitg00/agentmemory · error · Error
query is required
Error message
query is required
What it means
Both memory_recall and memory_smart_search require a non-empty string query argument. validate() throws when query is absent, not a string, or blank after trimming.
Source
Thrown at src/mcp/standalone.ts:148
v.type = (args["type"] as string) || "fact";
v.concepts = normalizeList(args["concepts"]);
v.files = normalizeList(args["files"]);
// The tool schema exposes project (and now agentId); dropping them
// here silently broke project/agent scoping through the stdio
// package specifically.
if (typeof args["project"] === "string" && args["project"].trim()) {
v.project = args["project"].trim();
}
if (typeof args["agentId"] === "string" && args["agentId"].trim()) {
v.agentId = args["agentId"].trim();
}
return v;
}
case "memory_recall":
case "memory_smart_search": {
const query = args["query"];
if (typeof query !== "string" || !query.trim()) {
throw new Error("query is required");
}
v.query = query.trim();
v.limit = parseLimit(args["limit"]);
const fmt = args["format"];
if (typeof fmt === "string" && fmt.trim()) {
v.format = fmt.trim().toLowerCase();
}
const budget = args["token_budget"];
if (typeof budget === "number" && Number.isFinite(budget) && budget > 0) {
v.tokenBudget = Math.floor(budget);
} else if (typeof budget === "string" && budget.trim()) {
const n = Number(budget);
if (Number.isFinite(n) && n > 0) v.tokenBudget = Math.floor(n);
}
return v;
}
case "memory_sessions": {
v.limit = parseLimit(args["limit"], 20);View on GitHub (pinned to e04ba88819)
Solutions
- Provide a non-empty search string in args.query.
- Guard the caller: skip the recall call entirely when the user's input is empty.
- Trim and validate user input before forwarding it as the query.
Example fix
// before
await callTool("memory_recall", { query: userInput }); // userInput may be ""
// after
if (!userInput.trim()) return [];
await callTool("memory_recall", { query: userInput.trim() }); Defensive patterns
Strategy: validation
Validate before calling
function canRecall(args) {
return typeof args.query === "string" && args.query.trim().length > 0;
}
if (!canRecall(args)) return { skipped: true, results: [] }; // skip call entirely Type guard
function hasQuery(args: Record<string, unknown>): args is { query: string } & Record<string, unknown> {
return typeof args.query === "string" && args.query.trim().length > 0;
} Try / catch
try {
return await callTool("memory_recall", args);
} catch (e) {
if (e.message === "query is required") return { results: [] }; // empty input: no recall needed
throw e;
} Prevention
- Gate recall/search calls behind a non-empty-input check in the agent loop.
- Trim user input once at ingestion and reuse the trimmed value.
- Never forward raw UI form values as query without validation.
When it happens
Trigger: Calling memory_recall or memory_smart_search with no query key, query: null, a numeric query, or query: "" / whitespace.
Common situations: LLM agents issuing a recall 'just to check memory' without formulating a query; UI wiring passing an empty search box value; scripts that build args conditionally and drop the empty query key.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- mem::search: token_budget must be a positive integer
- content is required
- Unknown tool: ${toolName}
- memoryIds is required
- Invalid dateFrom: ${filter.dateFrom}
AI-assisted analysis of rohitg00/agentmemory@e04ba88819 (2026-08-30).
Data as JSON: /api/errors/6683a0643390daa3.
Report an issue: GitHub.