From 7ab5ccd6205a7f99489968c021164c5f3733bda4 Mon Sep 17 00:00:00 2001 From: pansz Date: Thu, 13 Aug 2026 20:28:17 +0800 Subject: [PATCH] fix(memory): tolerate null/empty operation field via zod catch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The memory tool operation schema is z.enum(["search"]).default("search"). Serialized to JSON Schema, this becomes a field that is simultaneously required, has a default, and has an enum with a single value — a contradictory shape that some reasoning models (notably MiniMax-M3) interpret as "send null to mean use the default". zod .default() fires for undefined/missing keys but not for explicit null or "", so those calls fail with "Invalid input: expected \"search\"" at the operation path before the tool ever runs. Add .catch("search") so any invalid operation value falls back to the only legal value, matching the schema semantic intent (search is the only operation). One-line change; the enum, default, and describe are unchanged, so upstream refactors that touch this field stay patch-friendly. --- packages/opencode/src/tool/memory.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/opencode/src/tool/memory.ts b/packages/opencode/src/tool/memory.ts index a2389ff36..f0f9721d2 100644 --- a/packages/opencode/src/tool/memory.ts +++ b/packages/opencode/src/tool/memory.ts @@ -5,7 +5,7 @@ import DESCRIPTION from "./memory.txt" import * as Tool from "./tool" const parameters = z.object({ - operation: z.enum(["search"]).default("search").describe("Memory operation to perform"), + operation: z.enum(["search"]).default("search").catch("search").describe("Memory operation to perform"), query: z.string().describe("Search query (BM25 over markdown bodies)"), scope: z.enum(["global", "projects", "sessions", "cc"]).optional().describe("Filter by memory scope"), scope_id: z