{"record":{"id":"a0065e8399b734fe","repo":"thedotmack/claude-mem","slug":"observation-search-query-is-required","errorCode":null,"errorMessage":"observation_search: \"query\" is required","messagePattern":"observation_search: \"query\" is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/servers/mcp-server.ts","lineNumber":311,"sourceCode":"    ...(args.platformSource !== undefined ? { platformSource: normalizeMcpPlatformSource(args.platformSource) } : {}),\n    ...(args.payload !== undefined ? { payload: args.payload } : {}),\n    ...(args.generate !== undefined ? { generate: args.generate } : {}),\n  };\n  const response = await ctx.client.recordEvent(request);\n  return formatJsonResult(response);\n});\n\ninterface ObservationSearchArgs {\n  projectId?: string;\n  query: string;\n  limit?: number;\n  platformSource?: string | null;\n}\n\nconst handleObservationSearch = wrapHandler('observation_search', async (args: ObservationSearchArgs) => {\n  const ctx = requireServerForObservationTool('observation_search');\n  if (typeof args?.query !== 'string' || args.query.trim().length === 0) {\n    throw new Error('observation_search: \"query\" is required');\n  }\n  const projectId = args.projectId && args.projectId.trim().length > 0 ? args.projectId : ctx.projectId;\n  const request: ServerSearchObservationsRequest = {\n    projectId,\n    query: args.query,\n    ...(args.limit !== undefined ? { limit: args.limit } : {}),\n    ...(args.platformSource !== undefined ? { platformSource: normalizeMcpPlatformSource(args.platformSource) } : {}),\n  };\n  const response = await ctx.client.searchObservations(request);\n  return formatJsonResult(response);\n});\n\ninterface ObservationContextArgs {\n  projectId?: string;\n  query: string;\n  limit?: number;\n  platformSource?: string | null;\n}","sourceCodeStart":293,"sourceCodeEnd":329,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/servers/mcp-server.ts#L293-L329","documentation":"The observation_search tool handler requires a 'query' argument and throws this error when it is missing, not a string, or blank after trimming. Search without a query is meaningless, so the handler fails fast before building the ServerSearchObservationsRequest.","triggerScenarios":"Invoking observation_search with args where query is undefined, null, a non-string, or '' / whitespace-only (handler check: typeof args?.query !== 'string' || args.query.trim().length === 0).","commonSituations":"Clients sending only limit or projectId; a UI passing an empty search box value straight through; refactors renaming query to q or searchTerm; agents constructing empty search calls to 'list all' observations.","solutions":["Supply a non-empty query string, e.g. { query: 'deployment errors' }","If you want unfiltered listing, use a broad query term or a different listing tool instead of an empty query","Guard the caller: if (!query?.trim()) skip the call or prompt the user for input","Verify the MCP client is not URL-encoding/trimming the query down to nothing"],"exampleFix":"// before\nawait callTool('observation_search', { limit: 10 });\n// after\nawait callTool('observation_search', { query: 'typescript build failure', limit: 10 });","handlingStrategy":"validation","validationCode":"function canSearch(args) {\n  return typeof args?.query === 'string' && args.query.trim().length > 0;\n}\nif (!canSearch(args)) return []; // skip the call instead of erroring","typeGuard":"function hasQuery(args: unknown): args is { query: string } & Record<string, unknown> {\n  return typeof (args as any)?.query === 'string' && (args as any).query.trim().length > 0;\n}","tryCatchPattern":"try {\n  return await callTool('observation_search', { query, limit });\n} catch (e) {\n  if (e instanceof Error && e.message.includes('\"query\" is required')) {\n    return { results: [], skipped: 'empty query' };\n  }\n  throw e;\n}","preventionTips":["Disable search UIs/agents when the query box is empty","Trim and check user input before forwarding it as query","Use a dedicated listing tool for unfiltered browsing rather than an empty query","Validate required fields against the tool schema in your MCP client wrapper"],"tags":["mcp","validation","search","missing-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}