{"record":{"id":"a8f4c60e4c1c90cf","repo":"CherryHQ/cherry-studio","slug":"errorcode-invalidparams","errorCode":"ErrorCode.InvalidParams","errorMessage":"Unknown action \"${action}\", expected update/append/search","messagePattern":"Unknown action \"(.+?)\", expected update/append/search","errorType":"validation","errorClass":"McpError","httpStatus":null,"severity":"error","filePath":"src/main/ai/mcp/servers/agentMemory.ts","lineNumber":161,"sourceCode":"\n    this.mcpServer.server.setRequestHandler(CallToolRequestSchema, async (request) => {\n      const toolName = request.params.name\n      const args = (request.params.arguments ?? {}) as Record<string, string | undefined>\n\n      try {\n        if (toolName !== 'memory') {\n          throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${toolName}`)\n        }\n        const action = args.action\n        switch (action) {\n          case 'update':\n            return await this.memoryUpdate(args)\n          case 'append':\n            return await this.memoryAppend(args)\n          case 'search':\n            return await this.memorySearch(args)\n          default:\n            throw new McpError(ErrorCode.InvalidParams, `Unknown action \"${action}\", expected update/append/search`)\n        }\n      } catch (error) {\n        const message = error instanceof Error ? error.message : String(error)\n        logger.error(`Tool error: ${toolName}`, { agentId: this.agentId, error: message })\n        return {\n          content: [{ type: 'text' as const, text: `Error: ${message}` }],\n          isError: true\n        }\n      }\n    })\n  }\n\n  private async getAgentDataPath(): Promise<string> {\n    // Deliberate existence check: memory writes must stop once the owning agent is gone.\n    const agent = agentService.getAgent(this.agentId)\n    if (!agent) throw new McpError(ErrorCode.InternalError, `Agent not found: ${this.agentId}`)\n    const assertedPath = await assertAgentDataDirectory(path.dirname(this.agentDataPath), this.agentId)\n    if (path.resolve(assertedPath) !== path.resolve(this.agentDataPath)) {","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/src/main/ai/mcp/servers/agentMemory.ts#L143-L179","documentation":"Inside the 'memory' tool handler, the 'action' argument is switched against update/append/search. Any other value (including undefined) falls to the default branch and throws McpError with ErrorCode.InvalidParams. The tool's inputSchema declares action as required with an enum of the three values, so a well-behaved client is pre-validated.","triggerScenarios":"Client calls the memory tool with action missing, empty, or set to a value like 'read', 'delete', 'clear', or 'UPDATE' (case-sensitive). Also fires if arguments is null and args.action becomes undefined.","commonSituations":"An LLM hallucinates a non-existent action; a client bypasses schema validation; case sensitivity trips up callers ('Update' vs 'update').","solutions":["Use one of the three exact values: 'update', 'append', 'search' (lowercase).","Ensure the arguments object includes action as a required field.","Validate client-side against the tool's inputSchema before calling."],"exampleFix":"// before\nawait callTool('memory', { action: 'read', query: 'facts' })\n\n// after\nawait callTool('memory', { action: 'search', query: 'facts' })","handlingStrategy":"validation","validationCode":"const MEMORY_ACTIONS = new Set(['update', 'append', 'search'])\nfunction validateMemoryArgs(args: unknown): asserts args is { action: 'update' | 'append' | 'search'; [k: string]: unknown } {\n  const a = (args as { action?: string })?.action\n  if (!a || !MEMORY_ACTIONS.has(a)) {\n    throw new Error(`action must be one of update/append/search, got: ${a}`)\n  }\n}","typeGuard":"function isMemoryAction(v: unknown): v is 'update' | 'append' | 'search' {\n  return v === 'update' || v === 'append' || v === 'search'\n}","tryCatchPattern":null,"preventionTips":["Validate action against the enum client-side before calling the tool.","Pass action as a lowercase string; the switch is case-sensitive.","Provide the full arguments object — do not leave arguments null."],"tags":["mcp","validation","invalid-params","agent-memory"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}