[BUG] Tool hooks not firing in TS SDK

Resolved 💬 5 comments Opened Sep 19, 2025 by gsabran Closed Jan 6, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

I'm trying to use the TS SDK to run Claude Code. I would like to use the pre/post tool use hooks. When I set the hooks, I don't see them firing (my logger is not hit) but I see an error being written to the stderr handler.

I could not find information or examples in the documentations for how to use those hooks beyond the type info that I'm following.

What Should Happen?

I'm expecting the hook to run, and to log the tool input.

Error Messages/Logs

Claude Code stderr: Error in hook callback hook_0: Error: Stream closed
    at BF1.sendRequest (file:///Users/guigui/.claude/local/node_modules/@anthropic-ai/claude-code/cli.js:3667:117)
    at Object.callback (file:///Users/guigui/.claude/local/node_modules/@anthropic-ai/claude-code/cli.js:3667:986)
    at uO9 (file:///Users/guigui/.claude/local/node_modules/@anthropic-ai/claude-code/cli.js:848:115)
    at file:///Users/guigui/.claude/local/node_modules/@anthropic-ai/claude-code/cli.js:842:1251
    at Array.map (<anonymous>)
    at m61 (file:///Users/guigui/.claude/local/node_modules/@anthropic-ai/claude-code/cli.js:842:1102)
    at m61.next (<anonymous>)
    at tLA (file:///Users/guigui/.claude/local/node_modules/@anthropic-ai/claude-code/cli.js:843:3624)
    at tLA.next (<anonymous>)
    at kW5 (file:///Users/guigui/.claude/local/node_modules/@anthropic-ai/claude-code/cli.js:3350:18593)

Steps to Reproduce

Here is how I'm using the SDK

const runningQuery = query({
	prompt: arrayToAsyncIterable(userMessages),
	options: {
		mcpServers: {
			command: {
				type: "http",
				url: `http://localhost:${port}${mcpEndpoint}`,
			},
		},
		permissionPromptToolName: "mcp__command__tool_approval",
		cwd: localExecutable.cwd,
		env: localExecutable.env,
		abortController,
		includePartialMessages: true,
		maxTurns: 100,
		resume: existingSessionId,
		stderr: (data: string) => {
			if (data.startsWith("Spawning Claude Code native binary")) {
                                 // Somehow this is logged to stderr. Not an error.
				return
			}
			logInfo(`Claude Code stderr: '${data}'`)
		},
		hooks: {
			PreToolUse: [
				{
					hooks: [
						async (
							input: HookInput, // Union of all hook input types
							toolUseID: string | undefined,
							options: { signal: AbortSignal },
						): Promise<SyncHookJSONOutput> => {
							logInfo(
								`PreToolUse hook called for tool use ${toolUseID}, input: ${JSON.stringify(input)}`,
							)
							return {
								continue: true,
							}
						},
					],
				},
			],
		},
	},
})

If I remove the hook, the error doesn't appear anymore.

Claude Model

None

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

1.0.119

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Warp

Additional Information

_No response_

View original on GitHub ↗

This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗