{"record":{"id":"3fbc3eb53f7034e0","repo":"CherryHQ/cherry-studio","slug":"invalidparams-3fbc3e","errorCode":"InvalidParams","errorMessage":"Unknown action \"${action}\", expected add/list/remove","messagePattern":"Unknown action \"(.+?)\", expected add/list/remove","errorType":"validation","errorClass":"McpError","httpStatus":null,"severity":"warning","filePath":"src/main/ai/mcp/servers/cherryAutonomyTools.ts","lineNumber":291,"sourceCode":"\n  handles(toolName: string): boolean {\n    return AUTONOMY_TOOLS.some((tool) => tool.name === toolName)\n  }\n\n  async call(toolName: string, args: Record<string, unknown>): Promise<CallToolResult> {\n    try {\n      switch (toolName) {\n        case CRON_TOOL_NAME: {\n          const action = args.action\n          switch (action) {\n            case 'add':\n              return await this.addJob(args)\n            case 'list':\n              return this.listJobs()\n            case 'remove':\n              return await this.removeJob(args)\n            default:\n              throw new McpError(ErrorCode.InvalidParams, `Unknown action \"${action}\", expected add/list/remove`)\n          }\n        }\n        case NOTIFY_TOOL_NAME:\n          return await this.sendNotification(args)\n        case CONFIG_TOOL_NAME: {\n          const action = args.action\n          switch (action) {\n            case 'status':\n              return this.configStatus()\n            case 'rename':\n              return this.configRename(args)\n            case 'add_channel':\n              return await this.configAddChannel(args)\n            case 'update_channel':\n              return await this.configUpdateChannel(args)\n            case 'remove_channel':\n              return await this.configRemoveChannel(args)\n            case 'reconnect_channel':","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/src/main/ai/mcp/servers/cherryAutonomyTools.ts#L273-L309","documentation":"Inside the CRON_TOOL case, args.action is dispatched over add/list/remove; any other value falls to default and throws an McpError with ErrorCode.InvalidParams. The tool's inputSchema declares action enum ['add','list','remove'] and required ['action'], so a non-enum or missing action is rejected at runtime.","triggerScenarios":"Calling the cron tool with action 'delete', 'create', 'get', undefined, or any value outside add/list/remove.","commonSituations":"Agent uses a synonym ('delete' instead of 'remove'); omits action; passes a typo like 'lst'; a stale client assumes an older action name.","solutions":["Use exactly one of 'add', 'list', or 'remove' for the cron tool's action field.","If validating client-side, constrain to the inputSchema enum before sending.","On error, surface the allowed set to the agent so it can retry with the correct verb."],"exampleFix":"// before\n{ action: 'delete', id: 'abc' }\n\n// after\n{ action: 'remove', id: 'abc' }","handlingStrategy":"validation","validationCode":"const CRON_ACTIONS = new Set(['add', 'list', 'remove'])\nfunction validateCronAction(action: unknown): 'add' | 'list' | 'remove' {\n  if (typeof action !== 'string' || !CRON_ACTIONS.has(action)) {\n    throw new Error(`Unknown cron action \"${action}\". Use add/list/remove.`)\n  }\n  return action as 'add' | 'list' | 'remove'\n}","typeGuard":"function isCronAction(v: unknown): v is 'add' | 'list' | 'remove' {\n  return v === 'add' || v === 'list' || v === 'remove'\n}","tryCatchPattern":"if (!isCronAction(args.action)) {\n  return { content: [{ type: 'text', text: `action must be add/list/remove` }], isError: true }\n}","preventionTips":["Constrain action to the enum before sending.","Use 'remove' not 'delete'.","Re-read the tool description if unsure of the action set."],"tags":["validation","cron","scheduling","mcp","cherry-autonomy"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}