{"record":{"id":"6683a0643390daa3","repo":"rohitg00/agentmemory","slug":"query-is-required","errorCode":null,"errorMessage":"query is required","messagePattern":"query is required","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/mcp/standalone.ts","lineNumber":148,"sourceCode":"      v.type = (args[\"type\"] as string) || \"fact\";\n      v.concepts = normalizeList(args[\"concepts\"]);\n      v.files = normalizeList(args[\"files\"]);\n      // The tool schema exposes project (and now agentId); dropping them\n      // here silently broke project/agent scoping through the stdio\n      // package specifically.\n      if (typeof args[\"project\"] === \"string\" && args[\"project\"].trim()) {\n        v.project = args[\"project\"].trim();\n      }\n      if (typeof args[\"agentId\"] === \"string\" && args[\"agentId\"].trim()) {\n        v.agentId = args[\"agentId\"].trim();\n      }\n      return v;\n    }\n    case \"memory_recall\":\n    case \"memory_smart_search\": {\n      const query = args[\"query\"];\n      if (typeof query !== \"string\" || !query.trim()) {\n        throw new Error(\"query is required\");\n      }\n      v.query = query.trim();\n      v.limit = parseLimit(args[\"limit\"]);\n      const fmt = args[\"format\"];\n      if (typeof fmt === \"string\" && fmt.trim()) {\n        v.format = fmt.trim().toLowerCase();\n      }\n      const budget = args[\"token_budget\"];\n      if (typeof budget === \"number\" && Number.isFinite(budget) && budget > 0) {\n        v.tokenBudget = Math.floor(budget);\n      } else if (typeof budget === \"string\" && budget.trim()) {\n        const n = Number(budget);\n        if (Number.isFinite(n) && n > 0) v.tokenBudget = Math.floor(n);\n      }\n      return v;\n    }\n    case \"memory_sessions\": {\n      v.limit = parseLimit(args[\"limit\"], 20);","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/rohitg00/agentmemory/blob/e04ba88819c365c9acf9d6661ea802143e728bd6/src/mcp/standalone.ts#L130-L166","documentation":"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.","triggerScenarios":"Calling memory_recall or memory_smart_search with no query key, query: null, a numeric query, or query: \"\" / whitespace.","commonSituations":"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.","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."],"exampleFix":"// before\nawait callTool(\"memory_recall\", { query: userInput }); // userInput may be \"\"\n// after\nif (!userInput.trim()) return [];\nawait callTool(\"memory_recall\", { query: userInput.trim() });","handlingStrategy":"validation","validationCode":"function canRecall(args) {\n  return typeof args.query === \"string\" && args.query.trim().length > 0;\n}\nif (!canRecall(args)) return { skipped: true, results: [] }; // skip call entirely","typeGuard":"function hasQuery(args: Record<string, unknown>): args is { query: string } & Record<string, unknown> {\n  return typeof args.query === \"string\" && args.query.trim().length > 0;\n}","tryCatchPattern":"try {\n  return await callTool(\"memory_recall\", args);\n} catch (e) {\n  if (e.message === \"query is required\") return { results: [] }; // empty input: no recall needed\n  throw e;\n}","preventionTips":["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."],"tags":["mcp","validation","arguments"],"backgroundTag":"missing-required-argument","analyzedSha":"e04ba88819c365c9acf9d6661ea802143e728bd6","analyzedAt":"2026-08-30T01:07:40.754Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}