From 89335578ffffc65504b2055c0c85aa7521e5e79b Mon Sep 17 00:00:00 2001 From: Ben Vargas Date: Fri, 22 Aug 2025 05:34:54 -0600 Subject: [PATCH] fix(claude-code): prevent "Right-hand side of instanceof is not an object" when SDK missing; improve CLI stability (#1146) * fix: handle missing @anthropic-ai/claude-code SDK gracefully Add defensive checks to prevent "Right-hand side of 'instanceof' is not an object" errors when the optional Claude Code SDK is not installed. Changes: - Check if AbortError exists before using instanceof - Check if query function exists before calling it - Provide clear error messages when SDK is missing This fixes the issue reported by users in v0.24.0 and v0.25.0 where Task Master would crash with instanceof errors when using the claude-code provider without the SDK installed. * chore: bump @anthropic-ai/claude-code to ^1.0.88 and regenerate lockfile --- .changeset/quiet-owls-fix-cli-sdk.md | 8 ++++++++ package-lock.json | 19 +++++++++---------- package.json | 2 +- .../custom-sdk/claude-code/language-model.js | 14 ++++++++++++-- 4 files changed, 30 insertions(+), 13 deletions(-) create mode 100644 .changeset/quiet-owls-fix-cli-sdk.md diff --git a/.changeset/quiet-owls-fix-cli-sdk.md b/.changeset/quiet-owls-fix-cli-sdk.md new file mode 100644 index 00000000..f64fa6c1 --- /dev/null +++ b/.changeset/quiet-owls-fix-cli-sdk.md @@ -0,0 +1,8 @@ +--- +"task-master-ai": patch +--- + +fix(claude-code): prevent crash/hang when the optional `@anthropic-ai/claude-code` SDK is missing by guarding `AbortError instanceof` checks and adding explicit SDK presence checks in `doGenerate`/`doStream`. Also bump the optional dependency to `^1.0.88` for improved export consistency. + +Related to JSON truncation handling in #920; this change addresses a separate error-path crash reported in #1142. + diff --git a/package-lock.json b/package-lock.json index 2bcc7263..d008553e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "task-master-ai", - "version": "0.24.0", + "version": "0.25.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "task-master-ai", - "version": "0.24.0", + "version": "0.25.0", "license": "MIT WITH Commons-Clause", "workspaces": [ "apps/*", @@ -81,21 +81,21 @@ "node": ">=18.0.0" }, "optionalDependencies": { - "@anthropic-ai/claude-code": "^1.0.25", + "@anthropic-ai/claude-code": "^1.0.88", "@biomejs/cli-linux-x64": "^1.9.4", "ai-sdk-provider-gemini-cli": "^0.1.1" } }, "apps/docs": { - "version": "0.0.0", + "version": "0.0.1", "devDependencies": { "mintlify": "^4.0.0" } }, "apps/extension": { - "version": "0.23.1", + "version": "0.24.0", "dependencies": { - "task-master-ai": "0.24.0" + "task-master-ai": "0.25.0" }, "devDependencies": { "@dnd-kit/core": "^6.3.1", @@ -2046,10 +2046,9 @@ } }, "node_modules/@anthropic-ai/claude-code": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-code/-/claude-code-1.0.34.tgz", - "integrity": "sha512-9mQd8hodE5/RxZnsWUCdLzqGUKuCzBczrfc2QfxrNSlvUFpOgTzjT1Zlww2vW9v0K1e5K9g1o08apqPl/QPmpw==", - "hasInstallScript": true, + "version": "1.0.88", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-code/-/claude-code-1.0.88.tgz", + "integrity": "sha512-Np6H4EjkbmNolUpx98DvqLXV/iJrw2y7dz2rDJ7av9ajMz6HZfB8bdJV5D75+jO+Gk1pvA54HCIm0c65lDrzcw==", "license": "SEE LICENSE IN README.md", "optional": true, "bin": { diff --git a/package.json b/package.json index 89518bc4..c9a00461 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "zod-to-json-schema": "^3.24.5" }, "optionalDependencies": { - "@anthropic-ai/claude-code": "^1.0.25", + "@anthropic-ai/claude-code": "^1.0.88", "@biomejs/cli-linux-x64": "^1.9.4", "ai-sdk-provider-gemini-cli": "^0.1.1" }, diff --git a/src/ai-providers/custom-sdk/claude-code/language-model.js b/src/ai-providers/custom-sdk/claude-code/language-model.js index 3bf7ef89..960da2d7 100644 --- a/src/ai-providers/custom-sdk/claude-code/language-model.js +++ b/src/ai-providers/custom-sdk/claude-code/language-model.js @@ -169,6 +169,11 @@ export class ClaudeCodeLanguageModel { const warnings = this.generateUnsupportedWarnings(options); try { + if (!query) { + throw new Error( + "Claude Code SDK is not installed. Please install '@anthropic-ai/claude-code' to use the claude-code provider." + ); + } const response = query({ prompt: messagesPrompt, options: queryOptions @@ -227,7 +232,7 @@ export class ClaudeCodeLanguageModel { finishReason = 'truncated'; // Skip re-throwing: fall through so the caller receives usable data } else { - if (error instanceof AbortError) { + if (AbortError && error instanceof AbortError) { throw options.abortSignal?.aborted ? options.abortSignal.reason : error; @@ -335,6 +340,11 @@ export class ClaudeCodeLanguageModel { const stream = new ReadableStream({ start: async (controller) => { try { + if (!query) { + throw new Error( + "Claude Code SDK is not installed. Please install '@anthropic-ai/claude-code' to use the claude-code provider." + ); + } const response = query({ prompt: messagesPrompt, options: queryOptions @@ -478,7 +488,7 @@ export class ClaudeCodeLanguageModel { } catch (error) { let errorToEmit; - if (error instanceof AbortError) { + if (AbortError && error instanceof AbortError) { errorToEmit = options.abortSignal?.aborted ? options.abortSignal.reason : error;