{"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":306,"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":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d768ba364302d12b76e69e4f021f0bb1d2d50ed6/src/servers/mcp-server.ts#L288-L324","documentation":"Validation error inside the observation_search tool handler. After requireServerForObservationTool() passes, the handler requires args.query to be a non-empty trimmed string and throws this plain Error otherwise. It fires before ServerClient.searchObservations() is called, so no /v1/search request leaves the process.","triggerScenarios":"Calling observation_search with query omitted, null, non-string, or whitespace-only. The handler explicitly checks typeof args?.query === 'string' && args.query.trim().length > 0.","commonSituations":"Caller passes only limit/platformSource and forgets the query term; an LLM sends an empty query expecting 'list all'; query built from an empty template variable.","solutions":["Pass a non-empty query string.","If you want an unfiltered listing, use timeline or get_observations instead — observation_search requires a text query by design.","Trim and length-check the query on the caller side before invoking."],"exampleFix":"// before\nawait tools.observation_search({ limit: 20 });\n// throws 'observation_search: \"query\" is required'\n\n// after\nawait tools.observation_search({ query: 'ModeManager fallback', limit: 20 });","handlingStrategy":"validation","validationCode":"if (typeof args?.query !== 'string' || args.query.trim().length === 0) {\n  return { content: [{ type: 'text', text: 'query is required for observation_search' }], isError: true };\n}","typeGuard":"function hasSearchQuery(v: unknown): v is { query: string; limit?: number } {\n  return typeof (v as any)?.query === 'string' && (v as any).query.trim().length > 0;\n}","tryCatchPattern":null,"preventionTips":["Trim the query client-side and reject empty strings before calling.","For unfiltered listings use timeline/get_observations, not observation_search.","Document that observation_search requires a text query by design."],"tags":["mcp","validation","observation-tools","search"],"backgroundTag":null,"analyzedSha":"d768ba364302d12b76e69e4f021f0bb1d2d50ed6","analyzedAt":"2026-08-12T23:52:55.241Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}